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 8240 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 8241 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 8242 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 7634 of file mhttpd.cxx.

◆ LOG2

#define LOG2   0.301029996

Definition at line 7635 of file mhttpd.cxx.

◆ LOG5

#define LOG5   0.698970005

Definition at line 7636 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 697 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 698 of file mhttpd.cxx.

◆ READ_HISTORY_DATA

#define READ_HISTORY_DATA   0x1

Definition at line 8326 of file mhttpd.cxx.

◆ READ_HISTORY_LAST_WRITTEN

#define READ_HISTORY_LAST_WRITTEN   0x4

Definition at line 8328 of file mhttpd.cxx.

◆ READ_HISTORY_RUNMARKER

#define READ_HISTORY_RUNMARKER   0x2

Definition at line 8327 of file mhttpd.cxx.

◆ RESPONSE_501

#define RESPONSE_501   3

Definition at line 14261 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14260 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14259 of file mhttpd.cxx.

◆ STRDUP

#define STRDUP (   x)    strdup(x)

Definition at line 8243 of file mhttpd.cxx.

◆ TEXT_SIZE

#define TEXT_SIZE   50000

Definition at line 699 of file mhttpd.cxx.

◆ WEB_BUFFER_SIZE

#define WEB_BUFFER_SIZE   (6*1024*1024)

Definition at line 511 of file mhttpd.cxx.

Function Documentation

◆ add_custom_path()

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

Definition at line 3575 of file mhttpd.cxx.

3576{
3577 // do not append custom path to absolute filenames
3578
3579 if (filename[0] == '/')
3580 return filename;
3581 if (filename[0] == DIR_SEPARATOR)
3582 return filename;
3583
3584 HNDLE hDB;
3586
3587 std::string custom_path = "";
3588
3589 int status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
3590
3591 if (status != DB_SUCCESS)
3592 return filename;
3593
3594 if (custom_path.length() < 1)
3595 return filename;
3596
3597 if ((custom_path == DIR_SEPARATOR_STR) || !strchr(custom_path.c_str(), DIR_SEPARATOR)) {
3598 cm_msg(MERROR, "add_custom_path", "ODB /Custom/Path has a forbidden value \"%s\", please change it", custom_path.c_str());
3599 return filename;
3600 }
3601
3602 custom_path = ss_replace_env_variables(custom_path);
3603
3604 std::string full_filename = custom_path;
3605 if (full_filename[full_filename.length()-1] != DIR_SEPARATOR)
3606 full_filename += DIR_SEPARATOR_STR;
3607 full_filename += filename;
3608
3609 return full_filename;
3610}
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3026
#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:930
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:13714
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 9786 of file mhttpd.cxx.

9787{
9788 std::string s;
9789 s += name; // FIXME: should be URI-encoded
9790 s += "=";
9791 s += value; // FIXME: should be URI-encoded
9792 return s;
9793}
#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 16216 of file mhttpd.cxx.

16217{
16218 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16219 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16220}
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:16189
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16202
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 10383 of file mhttpd.cxx.

10384{
10385 int seln = atoi(p->getparam("seln"));
10386 for (int i=0; i<seln; i++) {
10387 char str[256];
10388 sprintf(str, "sel%d", i);
10389
10390 std::string par = p->getparam(str);
10391 if (par.length() < 1)
10392 continue;
10393
10394 std::string event_name, tag_name;
10395 SplitEventAndTagNames(par, event_name, tag_name);
10396
10397 if (tag_name == "")
10398 continue;
10399
10400 HistVar v;
10401
10402 v.event_name = event_name;
10403 v.tag_name = tag_name;
10404 v.colour = NextHistPlotColour(hp);
10405 v.order = NextHistPlotOrder(hp);
10406
10407 hp.vars.push_back(v);
10408 }
10409}
const char * getparam(const char *param)
Definition mhttpd.cxx:776
INT i
Definition mdump.cxx:32
static void SplitEventAndTagNames(std::string var_name, std::string &event_name, std::string &tag_name)
Definition mhttpd.cxx:10157
static std::string NextHistPlotColour(const HistPlot &hp)
Definition mhttpd.cxx:10122
static int NextHistPlotOrder(const HistPlot &hp)
Definition mhttpd.cxx:10148
char str[256]
Definition odbhist.cxx:33
std::vector< HistVar > vars
Definition mhttpd.cxx:8357
std::string tag_name
Definition mhttpd.cxx:8333
int order
Definition mhttpd.cxx:8338
std::string colour
Definition mhttpd.cxx:8335
std::string event_name
Definition mhttpd.cxx:8332
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 13898 of file mhttpd.cxx.

13899{
13900 char expected_response[33];
13901
13902 //printf("HereA!\n");
13903
13904 /* Parse "Authorization:" header, fail fast on parse error */
13905 struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
13906
13907 if (!hdr)
13908 return "";
13909
13910 //printf("HereB!\n");
13911
13912 std::string user = find_var_mg(hdr, "username");
13913 std::string cnonce = find_var_mg(hdr, "cnonce");
13914 std::string response = find_var_mg(hdr, "response");
13915 std::string uri = find_var_mg(hdr, "uri");
13916 std::string qop = find_var_mg(hdr, "qop");
13917 std::string nc = find_var_mg(hdr, "nc");
13918 std::string nonce = find_var_mg(hdr, "nonce");
13919
13920 if (user.length()<1) return "";
13921 if (cnonce.length()<1) return "";
13922 if (response.length()<1) return "";
13923 if (uri.length()<1) return "";
13924 if (qop.length()<1) return "";
13925 if (nc.length()<1) return "";
13926 if (nonce.length()<1) return "";
13927
13928 if (xmg_check_nonce(nonce.c_str()) == 0) return "";
13929 //printf("HereB8!\n");
13930
13931 //printf("HereC!\n");
13932
13933 const char* uri_end = strchr(hm->uri.p, ' ');
13934 if (!uri_end) return "";
13935
13936 size_t uri_length = uri_end - hm->uri.p;
13937
13938 if (uri_length != uri.length())
13939 return "";
13940
13941 int cmp = strncmp(hm->uri.p, uri.c_str(), uri_length);
13942
13943 //printf("check URI: message %d %d [%d] authorization [%s]\n", (int)hm->uri.len, uri_length, cmp, uri);
13944
13945 if (cmp != 0)
13946 return "";
13947
13948 for (unsigned i=0; i<auth->passwords.size(); i++) {
13949 AuthEntry* e = &auth->passwords[i];
13950 if (e->username != user)
13951 continue;
13952 if (e->realm != auth->realm)
13953 continue;
13954 const char* f_ha1 = e->password.c_str();
13955 int uri_len = hm->uri.len;
13956 if (hm->uri.p[uri_len] == '?')
13957 uri_len += hm->query_string.len + 1; // "+1" accounts for the "?" character
13958 xmg_mkmd5resp(hm->method.p, hm->method.len,
13959 hm->uri.p, uri_len,
13960 f_ha1, strlen(f_ha1),
13961 nonce.c_str(), nonce.length(),
13962 nc.c_str(), nc.length(),
13963 cnonce.c_str(), cnonce.length(),
13964 qop.c_str(), qop.length(),
13965 expected_response);
13966 int cmp = strcasecmp(response.c_str(), expected_response);
13967 //printf("digest_auth: expected %s, got %s, cmp %d\n", expected_response, response.c_str(), cmp);
13968 if (cmp == 0) {
13969 return e->username;
13970 }
13971 }
13972
13973 return "";
13974}
std::vector< AuthEntry > passwords
Definition mhttpd.cxx:13732
std::string realm
Definition mhttpd.cxx:13730
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:13760
static int xmg_check_nonce(const char *nonce)
Definition mhttpd.cxx:13781
Definition mhttpd.cxx:13722
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 1883 of file mhttpd.cxx.

1884{
1885 HNDLE hKey;
1886 int status = db_find_key(hDB, 0, odb_path, &hKey);
1887 if (status == DB_SUCCESS) {
1888 cm_msg(MERROR, "check_obsolete_odb", "ODB \"%s\" is obsolete, please delete it.", odb_path);
1889 }
1890}
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 13394 of file mhttpd.cxx.

13395{
13396 HNDLE hDB, hKeyEq, hKey;
13397 RUNINFO_STR(runinfo_str);
13398 int i, status;
13399 KEY key;
13400
13401 /* check /Runinfo structure */
13403 assert(status == DB_SUCCESS);
13404
13405 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), FALSE);
13406 if (status == DB_STRUCT_MISMATCH) {
13407 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), TRUE);
13408 if (status == DB_SUCCESS) {
13409 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo corrected successfully");
13410 } else {
13411 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13412 return 0;
13413 }
13414 } else if (status == DB_NO_KEY) {
13415 cm_msg(MERROR, "check_odb_records", "ODB subtree /Runinfo does not exist");
13416 status = db_create_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str());
13417 if (status == DB_SUCCESS) {
13418 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo created successfully");
13419 } else {
13420 cm_msg(MERROR, "check_odb_records", "Cannot create ODB subtree /Runinfo, db_create_record() status %d", status);
13421 return 0;
13422 }
13423 } else if (status != DB_SUCCESS) {
13424 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13425 return 0;
13426 }
13427
13428 /* check /Equipment/<name>/Common structures */
13429 if (db_find_key(hDB, 0, "/equipment", &hKeyEq) == DB_SUCCESS) {
13430 for (i = 0 ;; i++) {
13431 db_enum_key(hDB, hKeyEq, i, &hKey);
13432 if (!hKey)
13433 break;
13434 db_get_key(hDB, hKey, &key);
13435
13437 if (status == DB_STRUCT_MISMATCH) {
13439 if (status == DB_SUCCESS) {
13440 cm_msg(MINFO, "check_odb_records", "ODB subtree /Equipment/%s/Common corrected successfully", key.name);
13441 } else {
13442 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13443 }
13444 } else if (status != DB_SUCCESS) {
13445 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13446 }
13447 }
13448 }
13449
13450 return CM_SUCCESS;
13451}
#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:12750
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:5790
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:12578
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 6742 of file mhttpd.cxx.

6743{
6744 HNDLE hkey;
6745 INT size;
6746 char str[256];
6747
6748 /* check for password */
6749 db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hkey);
6750 if (hkey) {
6751 size = sizeof(str);
6752 db_get_data(hDB, hkey, str, &size, TID_STRING);
6753 if (strcmp(password, str) == 0)
6754 return TRUE;
6755
6756 /* show web password page */
6757 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6758 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6759 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6760
6761 r->rsprintf("<html><head>\n");
6762 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6763 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6764 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6765 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6766
6767 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6768
6769 /* define hidden fields for current experiment and destination */
6770 if (redir[0])
6771 r->rsprintf("<input type=hidden name=redir value=\"%s\">\n", redir);
6772
6773 /*---- page header ----*/
6774 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6775
6776 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6777
6778 if (password[0])
6779 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6780
6781 r->rsprintf
6782 ("<tr><th>Please enter password to obtain write access</tr>\n");
6783 r->rsprintf("<tr><td align=center><input type=password name=wpwd></tr>\n");
6784 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6785
6786 r->rsprintf("</table>\n");
6787
6788 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6789 r->rsprintf("</form>\n");
6790 r->rsprintf("</body></html>\r\n");
6791
6792 return FALSE;
6793 } else
6794 return TRUE;
6795}
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:6310
#define HTTP_ENCODING
Definition mhttpd.cxx:213
const char * mhttpd_revision(void)
Definition mhttpd.cxx:836
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 10039 of file mhttpd.cxx.

10040{
10041 return cmp_names(a.c_str(), b.c_str()) < 0;
10042}
static int cmp_names(const void *a, const void *b)
Definition mhttpd.cxx:9981
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 10044 of file mhttpd.cxx.

10045{
10046 return a < b;
10047}
Here is the caller graph for this function:

◆ cmp_names()

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

Definition at line 9981 of file mhttpd.cxx.

9982{
9983 int i;
9984 const char*sa = (const char*)a;
9985 const char*sb = (const char*)b;
9986
9987 int debug = 0;
9988
9989 // Cannot use strcmp() because it does not know how to compare numerical values, e.g.
9990 // it thinks "111" is smaller than "9"
9991 //return strcmp(sa, sb);
9992
9993 if (debug)
9994 printf("compare [%s] and [%s]\n", sa, sb);
9995
9996 for (i=0; ; i++) {
9997 if (sa[i]==0 && sb[i]==0)
9998 return 0; // both strings have the same length and the same characters
9999
10000 //printf("index %d, char [%c] [%c], isdigit %d %d\n", i, sa[i], sb[i], isdigit(sa[i]), isdigit(sb[i]));
10001
10002 if (isdigit(sa[i]) && isdigit(sb[i])) {
10003 int va = atoi(sa+i);
10004 int vb = atoi(sb+i);
10005
10006 if (debug)
10007 printf("index %d, values %d %d\n", i, va, vb);
10008
10009 if (va < vb)
10010 return -1;
10011 else if (va > vb)
10012 return 1;
10013
10014 // values are equal, skip the the end of the digits, compare any trailing text
10015 continue;
10016 }
10017
10018 if (sa[i]==sb[i]) {
10019 continue;
10020 }
10021
10022 if (debug)
10023 printf("index %d, char [%c] [%c]\n", i, sa[i], sb[i]);
10024
10025 if (sa[i] == 0) // string sa is shorter
10026 return -1;
10027 else if (sb[i] == 0) // string sb is shorter
10028 return 1;
10029
10030 if (sa[i]<sb[i])
10031 return -1;
10032 else
10033 return 1;
10034 }
10035
10036 // NOT REACHED
10037}
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 10049 of file mhttpd.cxx.

10050{
10051 return cmp_names(a.name, b.name) < 0;
10052}
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 10107 of file mhttpd.cxx.

10108{
10109 return a.order < b.order;
10110}
Here is the caller graph for this function:

◆ ctrlc_handler()

void ctrlc_handler ( int  sig)

Definition at line 13458 of file mhttpd.cxx.

13459{
13460 _abort = true;
13461}
std::atomic_bool _abort
Definition mhttpd.cxx:13456
Here is the caller graph for this function:

◆ decode_cookies()

void decode_cookies ( Cookies c,
const http_message msg 
)

Definition at line 14212 of file mhttpd.cxx.

14213{
14214 // extract password cookies
14215
14216 char cookie_pwd[256]; // general access password
14217 char cookie_wpwd[256]; // "write mode" password
14218 char cookie_cpwd[256]; // custom page and javascript password
14219
14220 cookie_pwd[0] = 0;
14221 cookie_wpwd[0] = 0;
14222 cookie_cpwd[0] = 0;
14223
14224 std::string s = find_cookie_mg(msg, "midas_pwd");
14225 if (s.length() > 0) {
14226 mstrlcpy(cookie_pwd, s.c_str(), sizeof(cookie_pwd));
14227 cookie_pwd[strcspn(cookie_pwd, " ;\r\n")] = 0;
14228 }
14229
14230 s = find_cookie_mg(msg, "midas_wpwd");
14231 if (s.length()) {
14232 mstrlcpy(cookie_wpwd, s.c_str(), sizeof(cookie_pwd));
14233 cookie_wpwd[strcspn(cookie_wpwd, " ;\r\n")] = 0;
14234 }
14235
14236 s = find_cookie_mg(msg, "cpwd");
14237 if (s.length()) {
14238 mstrlcpy(cookie_cpwd, s.c_str(), sizeof(cookie_pwd));
14239 cookie_cpwd[strcspn(cookie_cpwd, " ;\r\n")] = 0;
14240 }
14241
14242 // extract refresh rate
14243 c->refresh = DEFAULT_REFRESH;
14244 s = find_cookie_mg(msg, "midas_refr");
14245 if (s.length() > 0)
14246 c->refresh = atoi(s.c_str());
14247
14248 // extract equipment expand flag
14249 //c->expand_equipment = 0;
14250 //s = find_cookie_mg(msg, "midas_expeq");
14251 //if (s.length() > 0)
14252 // c->expand_equipment = atoi(s.c_str());
14253
14254 c->cookie_pwd = cookie_pwd;
14255 c->cookie_wpwd = cookie_wpwd;
14256 c->cookie_cpwd = cookie_cpwd;
14257}
#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:14160
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 13200 of file mhttpd.cxx.

13201{
13202 char path[256];
13203
13204 //printf("decode_get: string [%s], decode_url %d, url [%s], query_string [%s]\n", string, decode_url, url, query_string);
13205
13206 Param* param = new Param();
13207
13208 param->initparam();
13209
13210 if (url)
13211 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13212 else {
13213 mstrlcpy(path, string + 1, sizeof(path)); /* strip leading '/' */
13214
13215 if (strchr(path, '?'))
13216 *strchr(path, '?') = 0;
13217 }
13218
13219 param->setparam("path", path);
13220
13221 assert(query_string != NULL);
13222
13223 decode_query(param, query_string);
13224
13225 param->setparam("query", query_string);
13226
13227 char dec_path[256];
13228 mstrlcpy(dec_path, path, sizeof(dec_path));
13229
13230 interprete(param, rr, NULL, c, dec_path, t);
13231
13232 param->freeparam();
13233 delete param;
13234}
char param[10][256]
Definition mana.cxx:250
void decode_query(Param *pp, const char *query_string)
Definition mhttpd.cxx:13175
void interprete(Param *p, Return *r, Attachment *a, const Cookies *c, const char *dec_path, RequestTrace *t)
Definition mhttpd.cxx:12256
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 13238 of file mhttpd.cxx.

13239{
13240 bool debug_decode_post = false;
13241
13242 Param* param = new Param;
13243
13244 param->initparam();
13245
13246 char path[256];
13247
13248 if (url)
13249 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13250 else {
13251 mstrlcpy(path, header + 1, sizeof(path)); /* strip leading '/' */
13252 if (strchr(path, '?'))
13253 *strchr(path, '?') = 0;
13254 if (strchr(path, ' '))
13255 *strchr(path, ' ') = 0;
13256 }
13257 param->setparam("path", path); // undecoded path
13258
13259 Attachment* a = new Attachment;
13260
13261 const char* pinit = string;
13262
13263 /* return if no boundary defined */
13264 if (!boundary[0])
13265 return;
13266
13267 if (strstr(string, boundary))
13268 string = strstr(string, boundary) + strlen(boundary);
13269
13270 if (debug_decode_post)
13271 printf("decode_post: -->[%s]<--\n", string);
13272
13273 do {
13274 //printf("decode_post: [%s]\n", string);
13275 if (strstr(string, "name=")) {
13276 const char* pitem = strstr(string, "name=") + 5;
13277 if (*pitem == '\"')
13278 pitem++;
13279
13280 //printf("decode_post: pitem [%s]\n", pitem);
13281
13282 if (strncmp(pitem, "attfile", 7) == 0) {
13283 int n = pitem[7] - '1';
13284
13285 char file_name[256];
13286 file_name[0] = 0;
13287
13288 /* evaluate file attachment */
13289 if (strstr(pitem, "filename=")) {
13290 const char* p = strstr(pitem, "filename=") + 9;
13291 if (*p == '\"')
13292 p++;
13293 if (strstr(p, "\r\n\r\n"))
13294 string = strstr(p, "\r\n\r\n") + 4;
13295 else if (strstr(p, "\r\r\n\r\r\n"))
13296 string = strstr(p, "\r\r\n\r\r\n") + 6;
13297
13298 mstrlcpy(file_name, p, sizeof(file_name));
13299
13300 char* pp = file_name;
13301 if (strchr(pp, '\"'))
13302 *strchr(pp, '\"') = 0;
13303
13304 /* set attachment filename */
13305 char str[256];
13306 sprintf(str, "attachment%d", n);
13307 if (debug_decode_post)
13308 printf("decode_post: [%s] = [%s]\n", str, file_name);
13309 param->setparam(str, file_name); // file_name should be decoded?
13310 }
13311
13312 /* find next boundary */
13313 const char* ptmp = string;
13314 const char* p = NULL;
13315 do {
13316 while (*ptmp != '-')
13317 ptmp++;
13318
13319 p = strstr(ptmp, boundary);
13320 if (p != NULL) {
13321 while (*p == '-')
13322 p--;
13323 if (*p == 10)
13324 p--;
13325 if (*p == 13)
13326 p--;
13327 p++;
13328 break;
13329 } else
13330 ptmp += strlen(ptmp);
13331
13332 } while (TRUE);
13333
13334 /* save pointer to file */
13335 if (file_name[0]) {
13336 size_t size = (POINTER_T) p - (POINTER_T) string;
13337 char* buf = (char*)malloc(size+1);
13338 if (!buf) {
13339 return;
13340 }
13341 memcpy(buf, string, size);
13342 buf[size] = 0; // make sure string is NUL terminated
13343 a->attachment_buffer[n] = buf;
13344 a->attachment_size[n] = size;
13345 if (debug_decode_post)
13346 printf("decode_post: attachment[%d] size %d data --->[%s]<---\n", n, (int)a->attachment_size[n], a->attachment_buffer[n]);
13347 }
13348
13349 string = strstr(p, boundary) + strlen(boundary);
13350 } else {
13351 const char* p = pitem;
13352 if (strstr(p, "\r\n\r\n"))
13353 p = strstr(p, "\r\n\r\n") + 4;
13354 else if (strstr(p, "\r\r\n\r\r\n"))
13355 p = strstr(p, "\r\r\n\r\r\n") + 6;
13356
13357 char* ppitem = (char*)strchr(pitem, '\"'); // NB: defeat "const char* string"
13358 if (ppitem)
13359 *ppitem = 0;
13360
13361 char* pb = (char*)(strstr(p, boundary)); // NB: defeat "const char* string"
13362 if (pb) {
13363 string = pb + strlen(boundary);
13364 *pb = 0;
13365 char* ptmp = (char*)(p + (strlen(p) - 1)); // NB: defeat "const char* string"
13366 while (*ptmp == '-' || *ptmp == '\n' || *ptmp == '\r')
13367 *ptmp-- = 0;
13368 } else {
13369 show_error(rr, "Invalid POST request");
13370 return;
13371 }
13372 if (debug_decode_post)
13373 printf("decode_post: [%s] = [%s]\n", pitem, p);
13374 param->setparam(pitem, p); // in decode_post()
13375 }
13376
13377 while (*string == '-' || *string == '\n' || *string == '\r')
13378 string++;
13379 }
13380
13381 } while ((POINTER_T) string - (POINTER_T) pinit < length);
13382
13383 char dec_path[256];
13384 mstrlcpy(dec_path, path, sizeof(dec_path));
13385
13386 interprete(param, rr, a, c, dec_path, t);
13387
13388 delete a;
13389 delete param;
13390}
char * attachment_buffer[3]
Definition mhttpd.cxx:69
size_t attachment_size[3]
Definition mhttpd.cxx:70
void initparam()
Definition mhttpd.cxx:719
DWORD n[4]
Definition mana.cxx:247
void show_error(Return *r, const char *error)
Definition mhttpd.cxx:1841
#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 13175 of file mhttpd.cxx.

13176{
13177 int len = strlen(query_string);
13178 char *buf = (char *)malloc(len+1);
13179 assert(buf != NULL);
13180 memcpy(buf, query_string, len+1);
13181 char* p = buf;
13182 p = strtok(p, "&");
13183 while (p != NULL) {
13184 char *pitem = p;
13185 p = strchr(p, '=');
13186 if (p != NULL) {
13187 *p++ = 0;
13188 urlDecode(pitem); // parameter name
13189 if (!equal_ustring(pitem, "format"))
13190 urlDecode(p); // parameter value
13191
13192 pp->setparam(pitem, p); // decoded query parameters
13193
13194 p = strtok(NULL, "&");
13195 }
13196 }
13197 free(buf);
13198}
void setparam(const char *param, const char *value)
Definition mhttpd.cxx:726
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3285
static void urlDecode(char *p)
Definition mhttpd.cxx:882
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 10487 of file mhttpd.cxx.

10488{
10489 /* delete variables according to "hist_order" */
10490
10491 while (1) {
10492 bool something_deleted = false;
10493 for (unsigned i=0; i<hp.vars.size(); i++) {
10494 if (hp.vars[i].order <= 0) {
10495 hp.vars.erase(hp.vars.begin() + i);
10496 something_deleted = true;
10497 }
10498 }
10499 if (!something_deleted)
10500 break;
10501 }
10502}
Here is the caller graph for this function:

◆ do_jrpc()

void do_jrpc ( Param p,
Return r 
)

Definition at line 4325 of file mhttpd.cxx.

4326{
4327 int status;
4328
4329 const char *name = p->getparam("name");
4330 const char *cmd = p->getparam("rcmd");
4331 const char *args = p->getparam("rarg");
4332
4333 if (!name || !cmd || !args) {
4335 r->rsprintf("<INVALID_ARGUMENTS>");
4336 return;
4337 }
4338
4340
4341 int buf_length = 1024;
4342
4343 int max_reply_length = atoi(p->getparam("max_reply_length"));
4344 if (max_reply_length > buf_length)
4345 buf_length = max_reply_length;
4346
4347 char* buf = (char*)malloc(buf_length);
4348 assert(buf != NULL);
4349
4350 buf[0] = 0;
4351
4352 HNDLE hconn;
4353
4354 status = cm_connect_client(name, &hconn);
4355
4356 if (status != RPC_SUCCESS) {
4357 r->rsprintf("<RPC_CONNECT_ERROR>%d</RPC_CONNECT_ERROR>", status);
4358 free(buf);
4359 return;
4360 }
4361
4362 status = rpc_client_call(hconn, RPC_JRPC, cmd, args, buf, buf_length);
4363
4364 if (status != RPC_SUCCESS) {
4365 r->rsprintf("<RPC_CALL_ERROR>%d</RPC_CALL_ERROR>", status);
4366 free(buf);
4367 return;
4368 }
4369
4370 r->rsprintf("%s", buf);
4371
4372 //status = cm_disconnect_client(hconn, FALSE);
4373
4374 free(buf);
4375}
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2781
#define RPC_SUCCESS
Definition midas.h:699
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13497
#define RPC_JRPC
Definition mrpc.h:130
void show_text_header(Return *r)
Definition mhttpd.cxx:1829
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 4019 of file mhttpd.cxx.

4020{
4021 static RPC_LIST rpc_list[] = {
4022 { 9999, "mhttpd_jrpc_rev0", {
4023 {TID_STRING, RPC_IN}, // arg0
4024 {TID_STRING, RPC_IN}, // arg1
4025 {TID_STRING, RPC_IN}, // arg2
4026 {TID_STRING, RPC_IN}, // arg3
4027 {TID_STRING, RPC_IN}, // arg4
4028 {TID_STRING, RPC_IN}, // arg5
4029 {TID_STRING, RPC_IN}, // arg6
4030 {TID_STRING, RPC_IN}, // arg7
4031 {TID_STRING, RPC_IN}, // arg8
4032 {TID_STRING, RPC_IN}, // arg9
4033 {0}} },
4034 { 0 }
4035 };
4036
4037 int count = 0, substring = 0, rpc;
4038
4039 const char *xname = p->getparam("name");
4040 const char *srpc = p->getparam("rpc");
4041
4042 if (!srpc || !xname) {
4044 r->rsprintf("<INVALID_ARGUMENTS>");
4045 return;
4046 }
4047
4048 char sname[256];
4049 mstrlcpy(sname, xname, sizeof(sname));
4050
4051 if (sname[strlen(sname)-1]=='*') {
4052 sname[strlen(sname)-1] = 0;
4053 substring = 1;
4054 }
4055
4056 rpc = atoi(srpc);
4057
4058 if (rpc<RPC_MIN_ID || rpc>RPC_MAX_ID) {
4060 r->rsprintf("<INVALID_RPC_ID>");
4061 return;
4062 }
4063
4064 rpc_list[0].id = rpc;
4066
4068 r->rsprintf("calling rpc %d | ", rpc);
4069
4070 if (1) {
4071 int status, i;
4072 char str[256];
4073 HNDLE hDB, hrootkey, hsubkey, hkey;
4074
4076
4077 /* find client which exports FCNA function */
4078 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4079 if (status == DB_SUCCESS) {
4080 for (i=0; ; i++) {
4081 status = db_enum_key(hDB, hrootkey, i, &hsubkey);
4083 break;
4084
4085 sprintf(str, "RPC/%d", rpc);
4086 status = db_find_key(hDB, hsubkey, str, &hkey);
4087 if (status == DB_SUCCESS) {
4088 char client_name[NAME_LENGTH];
4089 HNDLE hconn;
4090 int size;
4091
4092 size = sizeof(client_name);
4093 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4094 if (status != DB_SUCCESS)
4095 continue;
4096
4097 if (strlen(sname) > 0) {
4098 if (substring) {
4099 if (strstr(client_name, sname) != client_name)
4100 continue;
4101 } else {
4102 if (strcmp(sname, client_name) != 0)
4103 continue;
4104 }
4105 }
4106
4107 count++;
4108
4109 r->rsprintf("client %s", client_name);
4110
4111 status = cm_connect_client(client_name, &hconn);
4112 r->rsprintf(" %d", status);
4113
4114 if (status == RPC_SUCCESS) {
4115 status = rpc_client_call(hconn, rpc,
4116 p->getparam("arg0"),
4117 p->getparam("arg1"),
4118 p->getparam("arg2"),
4119 p->getparam("arg3"),
4120 p->getparam("arg4"),
4121 p->getparam("arg5"),
4122 p->getparam("arg6"),
4123 p->getparam("arg7"),
4124 p->getparam("arg8"),
4125 p->getparam("arg9")
4126 );
4127 r->rsprintf(" %d", status);
4128
4129 //status = cm_disconnect_client(hconn, FALSE);
4130 r->rsprintf(" %d", status);
4131 }
4132
4133 r->rsprintf(" | ");
4134 }
4135 }
4136 }
4137 }
4138
4139 r->rsprintf("rpc %d, called %d clients\n", rpc, count);
4140}
#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:11852
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11598
double count
Definition mdump.cxx:33
#define RPC_IN
Definition midas.h:1579
#define RPC_MAX_ID
Definition midas.h:1606
#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 4144 of file mhttpd.cxx.

4145{
4146 static RPC_LIST rpc_list[] = {
4147 { 9998, "mhttpd_jrpc_rev1", {
4148 {TID_STRING, RPC_OUT}, // return string
4149 {TID_INT, RPC_IN}, // return string max length
4150 {TID_STRING, RPC_IN}, // arg0
4151 {TID_STRING, RPC_IN}, // arg1
4152 {TID_STRING, RPC_IN}, // arg2
4153 {TID_STRING, RPC_IN}, // arg3
4154 {TID_STRING, RPC_IN}, // arg4
4155 {TID_STRING, RPC_IN}, // arg5
4156 {TID_STRING, RPC_IN}, // arg6
4157 {TID_STRING, RPC_IN}, // arg7
4158 {TID_STRING, RPC_IN}, // arg8
4159 {TID_STRING, RPC_IN}, // arg9
4160 {0}} },
4161 { 0 }
4162 };
4163
4164 int status, substring = 0, rpc;
4165
4166 const char *xname = p->getparam("name");
4167 const char *srpc = p->getparam("rpc");
4168
4169 if (!srpc || !xname) {
4171 r->rsprintf("<INVALID_ARGUMENTS>");
4172 return;
4173 }
4174
4175 char sname[256];
4176 mstrlcpy(sname, xname, sizeof(sname));
4177
4178 if (sname[strlen(sname)-1]=='*') {
4179 sname[strlen(sname)-1] = 0;
4180 substring = 1;
4181 }
4182
4183 rpc = atoi(srpc);
4184
4185 if (rpc<RPC_MIN_ID || rpc>RPC_MAX_ID) {
4187 r->rsprintf("<INVALID_RPC_ID>");
4188 return;
4189 }
4190
4191 rpc_list[0].id = rpc;
4193
4194 //printf("cm_register_functions() for format \'%s\' status %d\n", sformat, status);
4195
4197
4198 std::string reply_header;
4199 std::string reply_body;
4200
4201 //r->rsprintf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", HTTP_ENCODING);
4202 //r->rsprintf("<!-- created by MHTTPD on (timestamp) -->\n");
4203 //r->rsprintf("<jrpc_rev1>\n");
4204 //r->rsprintf(" <rpc>%d</rpc>\n", rpc);
4205
4206 if (1) {
4207 HNDLE hDB, hrootkey, hsubkey, hkey;
4208
4210
4211 int buf_length = 1024;
4212
4213 int max_reply_length = atoi(p->getparam("max_reply_length"));
4214 if (max_reply_length > buf_length)
4215 buf_length = max_reply_length;
4216
4217 char* buf = (char*)malloc(buf_length);
4218
4219 assert(buf != NULL);
4220
4221 /* find client which exports our RPC function */
4222 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4223 if (status == DB_SUCCESS) {
4224 for (int i=0; ; i++) {
4225 status = db_enum_key(hDB, hrootkey, i, &hsubkey);
4227 break;
4228
4229 char str[256];
4230 sprintf(str, "RPC/%d", rpc);
4231 status = db_find_key(hDB, hsubkey, str, &hkey);
4232 if (status == DB_SUCCESS) {
4233 char client_name[NAME_LENGTH];
4234 HNDLE hconn;
4235 int size;
4236
4237 size = sizeof(client_name);
4238 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4239 if (status != DB_SUCCESS)
4240 continue;
4241
4242 if (strlen(sname) > 0) {
4243 if (substring) {
4244 if (strstr(client_name, sname) != client_name)
4245 continue;
4246 } else {
4247 if (strcmp(sname, client_name) != 0)
4248 continue;
4249 }
4250 }
4251
4252 //r->rsprintf(" <client>\n");
4253 //r->rsprintf(" <name>%s</name>\n", client_name);
4254
4255 int connect_status = -1;
4256 int call_status = -1;
4257 int call_length = 0;
4258 int disconnect_status = -1;
4259
4260 connect_status = cm_connect_client(client_name, &hconn);
4261
4262 //r->rsprintf(" <connect_status>%d</connect_status>\n", status);
4263
4264 if (connect_status == RPC_SUCCESS) {
4265 buf[0] = 0;
4266
4267 call_status = rpc_client_call(hconn, rpc,
4268 buf,
4269 buf_length,
4270 p->getparam("arg0"),
4271 p->getparam("arg1"),
4272 p->getparam("arg2"),
4273 p->getparam("arg3"),
4274 p->getparam("arg4"),
4275 p->getparam("arg5"),
4276 p->getparam("arg6"),
4277 p->getparam("arg7"),
4278 p->getparam("arg8"),
4279 p->getparam("arg9")
4280 );
4281
4282 //r->rsprintf(" <rpc_status>%d</rpc_status>\n", status);
4284 //r->rsputs("<data>");
4285 //r->rsputs(buf);
4286 //r->rsputs("</data>\n");
4287
4288 if (call_status == RPC_SUCCESS) {
4289 call_length = strlen(buf);
4290 reply_body += buf;
4291 }
4292
4293 //disconnect_status = cm_disconnect_client(hconn, FALSE);
4294 //r->rsprintf(" <disconnect_status>%d</disconnect_status>\n", status);
4295 }
4296
4297 //r->rsprintf(" </client>\n");
4298
4299 if (reply_header.length() > 0)
4300 reply_header += " | ";
4301
4302 char tmp[256];
4303 sprintf(tmp, "%s %d %d %d %d", client_name, connect_status, call_status, disconnect_status, call_length);
4304 reply_header += tmp;
4305 }
4306 }
4307 }
4308
4309 free(buf);
4310 }
4311
4312 //r->rsprintf(" <called_clients>%d</called_clients>\n", count);
4313 //r->rsprintf("</jrpc_rev1>\n");
4314
4315 if (reply_header.length() > 0) {
4316 r->rsputs(reply_header.c_str());
4317 r->rsputs(" || ");
4318 r->rsputs(reply_body.c_str());
4319 r->rsputs("\n");
4320 }
4321}
void rsputs(const char *str)
Definition mhttpd.cxx:602
#define TID_INT
Definition midas.h:338
#define RPC_OUT
Definition midas.h:1580
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 3502 of file mhttpd.cxx.

3503{
3504 HNDLE hDB, hkeyval;
3505 KEY vkey;
3506 int i, n, size, ivalue;
3507 char str[256], data[256];
3508
3510
3511 /* separate source from operators */
3512 for (i=0 ; i<(int)strlen(src) ; i++)
3513 if (src[i] == '>' || src[i] == '&')
3514 break;
3515 strncpy(str, src, i);
3516 str[i] = 0;
3517
3518 /* strip trailing blanks */
3519 while (strlen(str) > 0 && str[strlen(str)-1] == ' ')
3520 str[strlen(str)-1] = 0;
3521
3522 db_find_key(hDB, 0, str, &hkeyval);
3523 if (!hkeyval) {
3524 cm_msg(MERROR, "evaluate_src", "Invalid Src key \"%s\" for Fill \"%s\"",
3525 src, key);
3526 return 0;
3527 }
3528
3529 db_get_key(hDB, hkeyval, &vkey);
3530 size = sizeof(data);
3531 db_get_value(hDB, 0, src, data, &size, vkey.type, FALSE);
3532 std::string value = db_sprintf(data, size, 0, vkey.type);
3533 if (equal_ustring(value.c_str(), "NAN"))
3534 return 0;
3535
3536 if (vkey.type == TID_BOOL) {
3537 *fvalue = (value[0] == 'y');
3538 } else
3539 *fvalue = atof(value.c_str());
3540
3541 /* evaluate possible operators */
3542 do {
3543 if (src[i] == '>' && src[i+1] == '>') {
3544 i+=2;
3545 n = atoi(src+i);
3546 while (src[i] == ' ' || isdigit(src[i]))
3547 i++;
3548 ivalue = (int)*fvalue;
3549 ivalue >>= n;
3550 *fvalue = ivalue;
3551 }
3552
3553 if (src[i] == '&') {
3554 i+=1;
3555 while (src[i] == ' ')
3556 i++;
3557 if (src[i] == '0' && src[i+1] == 'x')
3558 sscanf(src+2+i, "%x", &n);
3559 else
3560 n = atoi(src+i);
3561 while (src[i] == ' ' || isxdigit(src[i]) || src[i] == 'x')
3562 i++;
3563 ivalue = (int)*fvalue;
3564 ivalue &= n;
3565 *fvalue = ivalue;
3566 }
3567
3568 } while (src[i]);
3569
3570 return 1;
3571}
#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:10612
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 11031 of file mhttpd.cxx.

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

14161{
14162 const std::string cookies = find_header_mg(msg, "Cookie");
14163 if (cookies.length() < 1)
14164 return "";
14165 const char* p = strstr(cookies.c_str(), cookie_name);
14166 if (!p)
14167 return "";
14168 const char* v = p+strlen(cookie_name);
14169 if (*v != '=')
14170 return "";
14171 v++;
14172 //printf("cookie [%s] value [%s]\n", cookie_name, v);
14173 return v;
14174}
static const std::string find_header_mg(const struct http_message *msg, const char *name)
Definition mhttpd.cxx:14147
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 13677 of file mhttpd.cxx.

13678{
13679 std::string exptdir = cm_get_path();
13680
13681 if (try_file_mg(".", filename, path, fpp, trace) == SUCCESS)
13682 return SUCCESS;
13683
13684 if (try_file_mg(getenv("MIDAS_DIR"), filename, path, fpp, trace) == SUCCESS)
13685 return SUCCESS;
13686
13687 if (try_file_mg(exptdir.c_str(), filename, path, fpp, trace) == SUCCESS)
13688 return SUCCESS;
13689
13690 if (try_file_mg(getenv("MIDASSYS"), filename, path, fpp, trace) == SUCCESS)
13691 return SUCCESS;
13692
13693 // setup default filename
13694 try_file_mg(exptdir.c_str(), filename, path, NULL, false);
13695 return SS_FILE_ERROR;
13696}
std::string cm_get_path()
Definition midas.cxx:1552
#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:13644
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 14147 of file mhttpd.cxx.

14148{
14149 size_t nlen = strlen(name);
14150 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14151 if (msg->header_names[i].len != nlen)
14152 continue;
14153 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14154 continue;
14155 return mgstr(&msg->header_values[i]);
14156 }
14157 return "";
14158}
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:14142
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 3096 of file mhttpd.cxx.

3097{
3098 char str[256], *ps, *pt;
3099 BOOL in_script;
3100
3101 *edit = 0;
3102 *tail = 0;
3103 *format = 0;
3104 pwd[0] = 0;
3105 in_script = FALSE;
3106 strcpy(type, "text");
3107 do {
3108 while (*p && *p != '<')
3109 p++;
3110
3111 /* return if end of string reached */
3112 if (!*p)
3113 return NULL;
3114
3115 p++;
3116 while (*p && ((*p == ' ') || iscntrl(*p)))
3117 p++;
3118
3119 strncpy(str, p, 6);
3120 str[6] = 0;
3121 if (equal_ustring(str, "script"))
3122 in_script = TRUE;
3123
3124 strncpy(str, p, 7);
3125 str[7] = 0;
3126 if (equal_ustring(str, "/script"))
3127 in_script = FALSE;
3128
3129 strncpy(str, p, 4);
3130 str[4] = 0;
3131 if (equal_ustring(str, "odb ")) {
3132 ps = p - 1;
3133 p += 4;
3134 while (*p && ((*p == ' ') || iscntrl(*p)))
3135 p++;
3136
3137 do {
3138 strncpy(str, p, 7);
3139 str[7] = 0;
3140 if (equal_ustring(str, "format=")) {
3141 p += 7;
3142 if (*p == '\"') {
3143 p++;
3144 while (*p && *p != '\"')
3145 *format++ = *p++;
3146 *format = 0;
3147 if (*p == '\"')
3148 p++;
3149 } else {
3150 while (*p && *p != ' ' && *p != '>')
3151 *format++ = *p++;
3152 *format = 0;
3153 }
3154
3155 } else {
3156
3157 strncpy(str, p, 4);
3158 str[4] = 0;
3159 if (equal_ustring(str, "src=")) {
3160 p += 4;
3161 if (*p == '\"') {
3162 p++;
3163 while (*p && *p != '\"')
3164 *path++ = *p++;
3165 *path = 0;
3166 if (*p == '\"')
3167 p++;
3168 } else {
3169 while (*p && *p != ' ' && *p != '>')
3170 *path++ = *p++;
3171 *path = 0;
3172 }
3173 } else {
3174
3175 if (in_script)
3176 break;
3177
3178 strncpy(str, p, 5);
3179 str[5] = 0;
3180 if (equal_ustring(str, "edit=")) {
3181 p += 5;
3182
3183 if (*p == '\"') {
3184 p++;
3185 *edit = atoi(p);
3186 if (*p == '\"')
3187 p++;
3188 } else {
3189 *edit = atoi(p);
3190 while (*p && *p != ' ' && *p != '>')
3191 p++;
3192 }
3193
3194 } else {
3195
3196 strncpy(str, p, 5);
3197 str[5] = 0;
3198 if (equal_ustring(str, "type=")) {
3199 p += 5;
3200 if (*p == '\"') {
3201 p++;
3202 while (*p && *p != '\"')
3203 *type++ = *p++;
3204 *type = 0;
3205 if (*p == '\"')
3206 p++;
3207 } else {
3208 while (*p && *p != ' ' && *p != '>')
3209 *type++ = *p++;
3210 *type = 0;
3211 }
3212 } else {
3213 strncpy(str, p, 4);
3214 str[4] = 0;
3215 if (equal_ustring(str, "pwd=")) {
3216 p += 4;
3217 if (*p == '\"') {
3218 p++;
3219 while (*p && *p != '\"')
3220 *pwd++ = *p++;
3221 *pwd = 0;
3222 if (*p == '\"')
3223 p++;
3224 } else {
3225 while (*p && *p != ' ' && *p != '>')
3226 *pwd++ = *p++;
3227 *pwd = 0;
3228 }
3229 } else {
3230 if (strchr(p, '=')) {
3231 mstrlcpy(str, p, sizeof(str));
3232 pt = strchr(str, '=')+1;
3233 if (*pt == '\"') {
3234 pt++;
3235 while (*pt && *pt != '\"')
3236 pt++;
3237 if (*pt == '\"')
3238 pt++;
3239 *pt = 0;
3240 } else {
3241 while (*pt && *pt != ' ' && *pt != '>')
3242 pt++;
3243 *pt = 0;
3244 }
3245 if (tail[0]) {
3246 mstrlcat(tail, " ", 256);
3247 mstrlcat(tail, str, 256);
3248 } else {
3249 mstrlcat(tail, str, 256);
3250 }
3251 p += strlen(str);
3252 }
3253 }
3254 }
3255 }
3256 }
3257 }
3258
3259 while (*p && ((*p == ' ') || iscntrl(*p)))
3260 p++;
3261
3262 if (*p == '<') {
3263 cm_msg(MERROR, "find_odb_tag", "Invalid odb tag '%s'", ps);
3264 return NULL;
3265 }
3266 } while (*p != '>');
3267
3268 return ps;
3269 }
3270
3271 while (*p && *p != '>')
3272 p++;
3273
3274 } while (1);
3275
3276}
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 2137 of file mhttpd.cxx.

2138{
2139 HNDLE hDB, hkeyroot, hkey;
2140 KEY key;
2141 INT i, j, size;
2142 char data[1024];
2143 time_t now;
2144
2146 db_find_key(hDB, 0, path, &hkeyroot);
2147 assert(hkeyroot);
2148
2149 /* title row */
2150 //size = sizeof(str);
2151 //str[0] = 0;
2152 //db_get_value(hDB, 0, "/Experiment/Name", str, &size, TID_STRING, TRUE);
2153 time(&now);
2154
2155 bout += "<table border=3 cellpadding=1 class=\"dialogTable\">\n";
2156 char ctimebuf[32];
2157 ctime_r(&now, ctimebuf);
2158 bout += msprintf("<tr><th colspan=2>%s</tr>\n", ctimebuf);
2159 bout += msprintf("<tr><th colspan=2>%s</tr>\n", path);
2160
2161 /* enumerate subkeys */
2162 for (i = 0;; i++) {
2163 db_enum_link(hDB, hkeyroot, i, &hkey);
2164 if (!hkey)
2165 break;
2166 db_get_key(hDB, hkey, &key);
2167
2168 /* resolve links */
2169 if (key.type == TID_LINK) {
2170 db_enum_key(hDB, hkeyroot, i, &hkey);
2171 db_get_key(hDB, hkey, &key);
2172 }
2173
2174 if (key.type == TID_KEY) {
2175 /* for keys, don't display data value */
2176 bout += msprintf("<tr><td colspan=2>%s</td></tr>\n", key.name);
2177 } else {
2178 /* display single value */
2179 if (key.num_values == 1) {
2180 size = sizeof(data);
2181 db_get_data(hDB, hkey, data, &size, key.type);
2182 //printf("data size %d [%s]\n", size, data);
2183 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2184 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2185
2186 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2187 data_str = "(empty)";
2188 hex_str = "";
2189 }
2190
2191 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2192 //sprintf(b, "<tr><td>%s</td><td>%s (%s)</td></tr>\n", key.name, data_str, hex_str);
2193 bout += "<tr><td>";
2194 bout += key.name;
2195 bout += "</td><td>";
2196 bout += data_str;
2197 bout += " (";
2198 bout += hex_str;
2199 bout += ")</td></tr>\n";
2200 } else {
2201 bout += msprintf("<tr><td>%s</td><td>", key.name);
2202 bout += strencode2(data_str.c_str());
2203 bout += "</td></tr>\n";
2204 }
2205 } else {
2206 /* display first value */
2207 bout += msprintf("<tr><td rowspan=%d>%s</td>\n", key.num_values, key.name);
2208
2209 for (j = 0; j < key.num_values; j++) {
2210 size = sizeof(data);
2211 db_get_data_index(hDB, hkey, data, &size, j, key.type);
2212 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2213 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2214
2215 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2216 data_str = "(empty)";
2217 hex_str = "";
2218 }
2219
2220 if (j > 0) {
2221 bout += "<tr>";
2222 }
2223
2224 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2225 //sprintf(b, "<td>[%d] %s (%s)<br></td></tr>\n", j, data_str, hex_str);
2226 bout += "<td>[";
2227 bout += toString(j);
2228 bout += "] ";
2229 bout += data_str;
2230 bout += " (";
2231 bout += hex_str;
2232 bout += ")<br></td></tr>\n";
2233 } else {
2234 //sprintf(b, "<td>[%d] %s<br></td></tr>\n", j, data_str);
2235 bout += "<td>[";
2236 bout += toString(j);
2237 bout += "] ";
2238 bout += data_str;
2239 bout += "<br></td></tr>\n";
2240 }
2241 }
2242 }
2243 }
2244 }
2245
2246 bout += "</table>\n";
2247}
#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:10752
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6664
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5496
std::string strencode2(const char *text)
Definition mhttpd.cxx:2050
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 8610 of file mhttpd.cxx.

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

1136{
1137 std::string ext_upper;
1138 const char* p = filename;
1139 const char* last_dot = NULL;
1140 for (; *p; p++) {
1141 if (*p == '.')
1142 last_dot = p;
1143 if (*p == DIR_SEPARATOR)
1144 last_dot = NULL;
1145 }
1146
1147 if (last_dot) {
1148 p = last_dot;
1149 for (; *p; p++)
1150 ext_upper += toupper(*p);
1151 }
1152
1153 //printf("filename: [%s], ext [%s]\n", filename, ext_upper.c_str());
1154
1155 std::string type = GetMimetype(ext_upper);
1156 if (type.length() > 0)
1157 return type;
1158
1159 cm_msg(MERROR, "get_content_type", "Unknown HTTP Content-Type for resource file \'%s\', file extension \'%s\'", filename, ext_upper.c_str());
1160
1161 return "text/plain";
1162}
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 8527 of file mhttpd.cxx.

8528{
8529 //HNDLE hDB;
8530 int status;
8531
8532 time_t now = ss_time();
8533
8534 if (endtime == 0)
8535 endtime = now;
8536
8537 HistoryData hsxxx;
8538 HistoryData* hsdata = &hsxxx;
8539
8540 //cm_get_experiment_database(&hDB, NULL);
8541
8542 HistPlot hp;
8543 LoadHistPlotFromOdb(odb, &hp, group, panel);
8544
8545 double tstart = ss_millitime();
8546
8547 int flags = READ_HISTORY_LAST_WRITTEN;
8548
8549 status = read_history(hp, /*hDB, group, panel,*/ index, flags, endtime, endtime, 0, hsdata);
8550
8551 if (status != HS_SUCCESS) {
8552 //sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
8553 return status;
8554 }
8555
8556 if (!hsdata->have_last_written) {
8557 //sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
8558 return HS_FILE_ERROR;
8559 }
8560
8561 int count = 0;
8562 time_t tmin = endtime;
8563 time_t tmax = 0;
8564
8565 for (int k=0; k<hsdata->nvars; k++) {
8566 int i = hsdata->odb_index[k];
8567
8568 if (i<0)
8569 continue;
8570 if (index != -1 && index != i)
8571 continue;
8572
8573 time_t lw = hsdata->last_written[k];
8574
8575 if (lw==0) // no last_written for this variable, skip it.
8576 continue;
8577
8578 if (lw > endtime)
8579 lw = endtime; // just in case hs_get_last_written() returns dates in the "future" for this plot
8580
8581 if (lw > tmax)
8582 tmax = lw;
8583
8584 if (lw < tmin)
8585 tmin = lw;
8586
8587 count++;
8588
8589 //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);
8590 }
8591
8592 if (count == 0) // all variables have no last_written
8593 return HS_FILE_ERROR;
8594
8595 if (want_all)
8596 *plastwritten = tmin; // all variables have data
8597 else
8598 *plastwritten = tmax; // at least one variable has data
8599
8600 //printf("tmin %.0f, tmax %.0f, endtime %.0f, last written %.0f\n", (double)tmin, (double)tmax, (double)endtime, (double)*plastwritten);
8601
8602 double tend = ss_millitime();
8603
8604 if (/* DISABLES CODE */ (0))
8605 printf("get_hist_last_written: elapsed time %f ms\n", tend-tstart);
8606
8607 return HS_SUCCESS;
8608}
#define HS_FILE_ERROR
Definition midas.h:729
DWORD ss_millitime()
Definition system.cxx:3465
#define READ_HISTORY_LAST_WRITTEN
Definition mhttpd.cxx:8328
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 8163 of file mhttpd.cxx.

8164{
8165 int status;
8166 HNDLE hDB;
8167
8168 // history reconnect requested by watch callback?
8169
8170 if (gDoReloadHistory) {
8171 gDoReloadHistory = false;
8172 reset = true;
8173 }
8174
8175 // disconnect from previous history
8176
8177 if (reset && gMh) {
8178 gMh->hs_disconnect();
8179 delete gMh;
8180 gMh = NULL;
8181 gMhkey = 0;
8182 }
8183
8185 assert(status == CM_SUCCESS);
8186
8187 // setup a watch on history configuration
8188
8190 HNDLE hKey;
8191 gDoSetupHistoryWatch = false;
8192
8193 status = db_find_key(hDB, 0, "/Logger/History", &hKey);
8194 if (status == DB_SUCCESS)
8196
8197 status = db_find_key(hDB, 0, "/History/LoggerHistoryChannel", &hKey);
8198 if (status == DB_SUCCESS)
8200 }
8201
8202 // find out if ODB settings have changed and we need to connect to a different history channel
8203
8204 HNDLE hKey = 0;
8206 if (status != HS_SUCCESS)
8207 return gMh;
8208
8209 //printf("mh %p, hKey %d, mhkey %d\n", mh, hKey, mhkey);
8210
8211 if (gMh && hKey == gMhkey) // same channel as before
8212 return gMh;
8213
8214 if (gMh) {
8215 delete gMh;
8216 gMh = NULL;
8217 gMhkey = 0;
8218 }
8219
8221 if (status != HS_SUCCESS || gMh==NULL) {
8222 cm_msg(MERROR, "get_history", "Cannot configure history, hs_get_history() status %d", status);
8223 gMh = NULL;
8224 return NULL;
8225 }
8226
8227 gMhkey = hKey;
8228
8229 // cm_msg(MINFO, "get_history", "Reading history from channel \'%s\' type \'%s\'", mh->name, mh->type);
8230
8231 return gMh;
8232}
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:13592
#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:8151
static HNDLE gMhkey
Definition mhttpd.cxx:8159
static bool gDoReloadHistory
Definition mhttpd.cxx:8149
static MidasHistoryInterface * gMh
Definition mhttpd.cxx:8158
static bool gDoSetupHistoryWatch
Definition mhttpd.cxx:8148
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 16189 of file mhttpd.cxx.

16190{
16191 if (!params) {
16192 MJSO *doc = MJSO::I();
16193 doc->D("get current value of mhttpd http_trace");
16194 doc->P(NULL, 0, "there are no input parameters");
16195 doc->R(NULL, MJSON_INT, "current value of http_trace");
16196 return doc;
16197 }
16198
16199 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16200}
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:435
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 991 of file mhttpd.cxx.

992{
993 HNDLE hDB;
994 int status;
995
997
998 std::vector<std::string> paths;
999
1000 // add /Experiment/Resources
1001 std::string buf;
1002 status = db_get_value_string(hDB, 0, "/Experiment/Resources", 0, &buf, TRUE);
1003 if (status == DB_SUCCESS && buf.length() > 0)
1004 paths.push_back(buf);
1005
1006 // add "/Logger/History/IMAGE/History dir"
1007 paths.push_back(cm_get_history_path("IMAGE"));
1008
1009 // add /Logger/Data dir
1010 status = db_get_value_string(hDB, 0, "/Logger/Data dir", 0, &buf, TRUE);
1011 if (status == DB_SUCCESS && buf.length() > 0)
1012 paths.push_back(buf);
1013
1014 std::string cwd = ss_getcwd();
1015 if (!cwd.empty()) {
1016 paths.push_back(cwd + "/");
1017 paths.push_back(cwd + "/resources/");
1018 }
1019 paths.push_back(cm_get_path());
1020 paths.push_back(cm_get_path() + "resources/");
1021 char *m = getenv("MIDASSYS");
1022 if (m) {
1023 paths.push_back(std::string(m) + "/resources/");
1024 }
1025
1026 return paths;
1027}
std::string cm_get_history_path(const char *history_channel)
Definition midas.cxx:5860
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 376 of file mhttpd.cxx.

377{
378 struct timeval tv;
379 gettimeofday(&tv, NULL);
380 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
381}
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 14263 of file mhttpd.cxx.

14264{
14265 Cookies cookies;
14266
14267 decode_cookies(&cookies, msg);
14268
14269 // lock shared structures
14270
14271#ifdef HAVE_MONGOOSE6
14272 int status = ss_mutex_wait_for(request_mutex, 0);
14273 assert(status == SS_SUCCESS);
14274#endif
14275
14276 //t->fTimeLocked = GetTimeSec();
14277
14278 // prepare return buffer
14279
14280 Return *rr = new Return();
14281
14282 rr->zero();
14283
14284 // call midas
14285
14286 decode_get(rr, NULL, &cookies, uri, query_string, t);
14287
14288 if (trace_mg)
14289 printf("handle_decode_get: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14290
14292
14293 if (rr->return_length == -1) {
14294 delete rr;
14295#ifdef HAVE_MONGOOSE6
14296 //t->fTimeUnlocked = GetTimeSec();
14297 ss_mutex_release(request_mutex);
14298#endif
14299 return RESPONSE_501;
14300 }
14301
14302 if (rr->return_length == 0)
14303 rr->return_length = strlen(rr->return_buffer);
14304
14305 //t->fTimeUnlocked = GetTimeSec();
14306
14307#ifdef HAVE_MONGOOSE6
14308 ss_mutex_release(request_mutex);
14309#endif
14310
14311 mg_send(nc, rr->return_buffer, rr->return_length);
14312
14313 if (!strstr(rr->return_buffer, "Content-Length")) {
14314 // cannot do pipelined http if response generated by mhttpd
14315 // decode_get() has no Content-Length header.
14316 // must close the connection.
14318 }
14319
14320 t->fTimeSent = GetTimeSec();
14321
14322 delete rr;
14323
14324 return RESPONSE_SENT;
14325}
double fTimeSent
Definition mhttpd.cxx:392
double fTimeProcessed
Definition mhttpd.cxx:391
void zero()
Definition mhttpd.cxx:549
int return_length
Definition mhttpd.cxx:521
char * return_buffer
Definition mhttpd.cxx:518
#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:13710
#define RESPONSE_501
Definition mhttpd.cxx:14261
void decode_cookies(Cookies *c, const http_message *msg)
Definition mhttpd.cxx:14212
void decode_get(Return *rr, char *string, const Cookies *c, const char *url, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:13200
#define RESPONSE_SENT
Definition mhttpd.cxx:14259
static double GetTimeSec()
Definition mhttpd.cxx:376
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 14733 of file mhttpd.cxx.

14734{
14735
14736 char boundary[256];
14737 boundary[0] = 0;
14738 const std::string ct = find_header_mg(msg, "Content-Type");
14739 if (ct.length() > 0) {
14740 const char* s = strstr(ct.c_str(), "boundary=");
14741 if (s)
14742 mstrlcpy(boundary, s+9, sizeof(boundary));
14743 }
14744
14745#ifdef HAVE_MONGOOSE616
14746 if (multithread_mg)
14747 return queue_decode_post(nc, msg, boundary, uri, query_string, t);
14748#endif
14749
14750 Cookies cookies;
14751
14752 decode_cookies(&cookies, msg);
14753
14754 const char* post_data = msg->body.p;
14755 int post_data_len = msg->body.len;
14756
14757 // lock shared strctures
14758
14759#ifdef HAVE_MONGOOSE6
14760 int status = ss_mutex_wait_for(request_mutex, 0);
14761 assert(status == SS_SUCCESS);
14762#endif
14763
14764 // prepare return buffer
14765
14766 Return* rr = new Return;
14767
14768 rr->zero();
14769
14770 //printf("post_data_len %d, data [%s], boundary [%s]\n", post_data_len, post_data, boundary);
14771
14772 decode_post(rr, NULL, (char*)post_data, boundary, post_data_len, &cookies, uri, t);
14773
14774 if (trace_mg)
14775 printf("handle_decode_post: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14776
14777 if (rr->return_length == -1) {
14778#ifdef HAVE_MONGOOSE6
14779 ss_mutex_release(request_mutex);
14780#endif
14781 delete rr;
14782 return RESPONSE_501;
14783 }
14784
14785 if (rr->return_length == 0)
14786 rr->return_length = strlen(rr->return_buffer);
14787
14788#ifdef HAVE_MONGOOSE6
14789 ss_mutex_release(request_mutex);
14790#endif
14791
14792 mg_send(nc, rr->return_buffer, rr->return_length);
14793
14794 if (!strstr(rr->return_buffer, "Content-Length")) {
14795 // cannot do pipelined http if response generated by mhttpd
14796 // decode_get() has no Content-Length header.
14797 // must close the connection.
14799 }
14800
14801 delete rr;
14802
14803 return RESPONSE_SENT;
14804}
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:13238
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 14178 of file mhttpd.cxx.

14179{
14180 struct mbuf *io = &nc->recv_mbuf;
14181 switch (ev) {
14182 case MG_EV_POLL: // periodic call from loop_mg() via mg_mgr_poll()
14183 break;
14184 case MG_EV_ACCEPT:
14185 if (trace_mg)
14186 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> accept\n", nc, ev, ev_data);
14187 break;
14188 case MG_EV_RECV:
14189 if (trace_mg)
14190 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);
14191#if 0
14192 // This event handler implements simple TCP echo server
14193 mg_send(nc, io->buf, io->len); // Echo received data back
14194 mbuf_remove(io, io->len); // Discard data from recv buffer
14195#endif
14196 break;
14197 case MG_EV_SEND:
14198 if (trace_mg)
14199 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> send %d bytes\n", nc, ev, ev_data, *(int*)ev_data);
14200 break;
14201 case MG_EV_CLOSE:
14202 if (trace_mg)
14203 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> close\n", nc, ev, ev_data);
14204 break;
14205 default:
14206 if (trace_mg)
14207 printf("handle_event_mg: nc %p, ev %d, ev_data %p\n", nc, ev, ev_data);
14208 break;
14209 }
14210}
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 14806 of file mhttpd.cxx.

14807{
14808 std::string query_string = mgstr(&msg->query_string);
14809
14810 if (trace_mg||verbose_mg)
14811 printf("handle_http_get: uri [%s], query [%s]\n", uri, query_string.c_str());
14812
14813 if (query_string == "mjsonrpc_schema") {
14814 MJsonNode* s = mjsonrpc_get_schema();
14815 std::string reply = s->Stringify();
14816 delete s;
14817
14818 int reply_length = reply.length();
14819
14820 const std::string origin_header = find_header_mg(msg, "Origin");
14821
14822 std::string headers;
14823 headers += "HTTP/1.1 200 OK\n";
14824 if (origin_header.length() > 0)
14825 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14826 else
14827 headers += "Access-Control-Allow-Origin: *\n";
14828 headers += "Access-Control-Allow-Credentials: true\n";
14829 headers += "Content-Length: " + toString(reply_length) + "\n";
14830 headers += "Content-Type: application/json\n";
14831 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14832
14833 //printf("sending headers: %s\n", headers.c_str());
14834 //printf("sending reply: %s\n", reply.c_str());
14835
14836 std::string send = headers + "\n" + reply;
14837
14839
14840 mg_send(nc, send.c_str(), send.length());
14841
14842 t->fTimeSent = GetTimeSec();
14843
14844 return RESPONSE_SENT;
14845 }
14846
14847 if (query_string == "mjsonrpc_schema_text") {
14848 MJsonNode* s = mjsonrpc_get_schema();
14849 std::string reply = mjsonrpc_schema_to_text(s);
14850 delete s;
14851
14852 int reply_length = reply.length();
14853
14854 const std::string origin_header = find_header_mg(msg, "Origin");
14855
14856 std::string headers;
14857 headers += "HTTP/1.1 200 OK\n";
14858 if (origin_header.length() > 0)
14859 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14860 else
14861 headers += "Access-Control-Allow-Origin: *\n";
14862 headers += "Access-Control-Allow-Credentials: true\n";
14863 headers += "Content-Length: " + toString(reply_length) + "\n";
14864 headers += "Content-Type: text/plain\n";
14865 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14866
14867 //printf("sending headers: %s\n", headers.c_str());
14868 //printf("sending reply: %s\n", reply.c_str());
14869
14870 std::string send = headers + "\n" + reply;
14871
14873
14874 mg_send(nc, send.c_str(), send.length());
14875
14876 t->fTimeSent = GetTimeSec();
14877
14878 return RESPONSE_SENT;
14879 }
14880
14881#ifdef HAVE_MONGOOSE616
14882 if (multithread_mg)
14883 return queue_decode_get(nc, msg, uri, query_string.c_str(), t);
14884#endif
14885
14886 return handle_decode_get(nc, msg, uri, query_string.c_str(), t);
14887}
MJsonNode * mjsonrpc_get_schema()
std::string mjsonrpc_schema_to_text(const MJsonNode *schema)
static bool verbose_mg
Definition mhttpd.cxx:13709
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:14263
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 15085 of file mhttpd.cxx.

15086{
15087 std::string method = mgstr(&msg->method);
15088 std::string query_string = mgstr(&msg->query_string);
15089 std::string uri_encoded = mgstr(&msg->uri);
15090 std::string uri = UrlDecode(uri_encoded.c_str());
15091
15092 if (trace_mg)
15093 printf("handle_http_message: method [%s] uri [%s] proto [%s]\n", method.c_str(), uri.c_str(), mgstr(&msg->proto).c_str());
15094
15095 RequestTrace* t = new RequestTrace;
15097 t->fMethod = method;
15098 t->fUri = uri;
15099 t->fQuery = query_string;
15100
15101 // process OPTIONS for Cross-origin (CORS) preflight request
15102 // see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
15103 if (method == "OPTIONS" && query_string == "mjsonrpc" && mg_get_http_header(msg, "Access-Control-Request-Method") != NULL) {
15104 handle_http_options_cors(nc, msg, t);
15105 t->fCompleted = true;
15107 return;
15108 }
15109
15111 std::string username = check_digest_auth(msg, gAuthMg);
15112
15113 // Cannot re-read the password file - it is not thread safe to do so
15114 // unless I lock gAuthMg for each call check_digest_auth() and if I do so,
15115 // I will serialize (single-thread) all the http requests and defeat
15116 // the whole point of multithreading the web server. K.O.
15117 //
15119 //if (username.length() < 1) {
15120 // bool ok = read_passwords(&gAuthMg);
15121 // if (ok)
15122 // username = check_digest_auth(msg, &gAuthMg);
15123 //}
15124
15125 if (trace_mg)
15126 printf("handle_http_message: auth user: \"%s\"\n", username.c_str());
15127
15128 if (username.length() == 0) {
15129 if (trace_mg||verbose_mg)
15130 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());
15131
15133 t->fCompleted = true;
15135 return;
15136 }
15137 t->fAuthOk = true;
15138 } else {
15139 t->fAuthOk = true;
15140 }
15141
15142#ifdef HAVE_MONGOOSE616
15143 if (gProxyOdb && starts_with(uri, "/proxy/")) {
15144 std::string::size_type p1 = uri.find("/", 1);
15145 if (p1 == uri.length()-1) {
15146 std::string response = "404 Not Found (Proxy name is missing)";
15147 mg_send_head(nc, 404, response.length(), NULL);
15148 mg_send(nc, response.c_str(), response.length());
15149 delete t;
15150 return;
15151 }
15152 std::string::size_type p2 = uri.find("/", p1+1);
15153 if (p2 == std::string::npos) {
15154 std::string response = "404 Not Found (Proxy URL should end with a slash)";
15155 mg_send_head(nc, 404, response.length(), NULL);
15156 mg_send(nc, response.c_str(), response.length());
15157 delete t;
15158 return;
15159 }
15160 std::string p = uri.substr(p1+1, p2-p1-1);
15161 //printf("uri [%s], p1: %d, p2: %d, substr: [%s]\n", uri.c_str(), (int)p1, (int)p2, p.c_str());
15162 if (p.length() < 1) {
15163 std::string response = "404 Not Found (Double-slash or Proxy name is too short)";
15164 mg_send_head(nc, 404, response.length(), NULL);
15165 mg_send(nc, response.c_str(), response.length());
15166 delete t;
15167 return;
15168 }
15169 std::string destination;
15170 gProxyOdb->RS(p.c_str(), &destination);
15171 if (destination.length() < 1) {
15172 std::string response = "404 Not Found (Proxy not found in ODB)";
15173 mg_send_head(nc, 404, response.length(), NULL);
15174 mg_send(nc, response.c_str(), response.length());
15175 delete t;
15176 return;
15177 } else if (destination[0] == '#') {
15178 std::string response = "404 Not Found (Proxy commented-out in ODB)";
15179 mg_send_head(nc, 404, response.length(), NULL);
15180 mg_send(nc, response.c_str(), response.length());
15181 delete t;
15182 return;
15183 } else if (ends_with_char(destination, '/')) {
15184 std::string response = "404 Not Found (Proxy address should not end with a slash)";
15185 mg_send_head(nc, 404, response.length(), NULL);
15186 mg_send(nc, response.c_str(), response.length());
15187 delete t;
15188 return;
15189 } else if (!starts_with(destination, "http")) {
15190 std::string response = "404 Not Found (Proxy address does not start with http";
15191 mg_send_head(nc, 404, response.length(), NULL);
15192 mg_send(nc, response.c_str(), response.length());
15193 delete t;
15194 return;
15195 } else {
15196 std::string m;
15197 m += "/proxy";
15198 m += "/";
15199 m += p;
15200 mg_str mount = mg_mk_str(m.c_str());
15201 mg_str upstream = mg_mk_str(destination.c_str());
15202 if (verbose_mg||trace_mg) {
15203 printf("proxy: uri [%s] mount [%s] upstream [%s]\n", uri.c_str(), mgstr(&mount).c_str(), mgstr(&upstream).c_str());
15204 }
15205 mg_http_reverse_proxy(nc, msg, mount, upstream);
15206 delete t;
15207 return;
15208 }
15209 }
15210#endif
15211
15212 int response = RESPONSE_501;
15213
15214 if (method == "GET")
15215 response = handle_http_get(nc, msg, uri.c_str(), t);
15216 else if (method == "POST")
15217 response = handle_http_post(nc, msg, uri.c_str(), t);
15218
15219 if (response == RESPONSE_501) {
15220 if (trace_mg||verbose_mg)
15221 printf("handle_http_message: sending 501 Not Implemented error\n");
15222
15223 std::string response = "501 Not Implemented";
15224 mg_send_head(nc, 501, response.length(), NULL); // 501 Not Implemented
15225 mg_send(nc, response.c_str(), response.length());
15226 }
15227
15228 if (response != RESPONSE_QUEUED) {
15229 t->fCompleted = true;
15231 }
15232}
void AddTraceMTS(RequestTrace *t)
Definition mhttpd.cxx:463
std::string fQuery
Definition mhttpd.cxx:396
std::string fMethod
Definition mhttpd.cxx:394
std::string fUri
Definition mhttpd.cxx:395
bool fCompleted
Definition mhttpd.cxx:393
double fTimeReceived
Definition mhttpd.cxx:388
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:14889
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:13898
static std::string UrlDecode(const char *p)
Definition mhttpd.cxx:843
bool starts_with(const std::string &s1, const char *s2)
Definition mhttpd.cxx:4438
#define RESPONSE_QUEUED
Definition mhttpd.cxx:14260
static int handle_http_get(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14806
static RequestTraceBuf * gTraceBuf
Definition mhttpd.cxx:506
static void xmg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
Definition mhttpd.cxx:13792
static void handle_http_options_cors(struct mg_connection *nc, const http_message *msg, RequestTrace *t)
Definition mhttpd.cxx:15015
static Auth * gAuthMg
Definition mhttpd.cxx:13758
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 15015 of file mhttpd.cxx.

15016{
15017 //
15018 // JSON-RPC CORS pre-flight request, see
15019 // https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
15020 //
15021 // OPTIONS /resources/post-here/ HTTP/1.1
15022 // Host: bar.other
15023 // User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
15024 // Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
15025 // Accept-Language: en-us,en;q=0.5
15026 // Accept-Encoding: gzip,deflate
15027 // Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
15028 // Connection: keep-alive
15029 // Origin: http://foo.example
15030 // Access-Control-Request-Method: POST
15031 // Access-Control-Request-Headers: X-PINGOTHER
15032 //
15033 // HTTP/1.1 200 OK
15034 // Date: Mon, 01 Dec 2008 01:15:39 GMT
15035 // Server: Apache/2.0.61 (Unix)
15036 // Access-Control-Allow-Origin: http://foo.example
15037 // Access-Control-Allow-Methods: POST, GET, OPTIONS
15038 // Access-Control-Allow-Headers: X-PINGOTHER
15039 // Access-Control-Max-Age: 1728000
15040 // Vary: Accept-Encoding, Origin
15041 // Content-Encoding: gzip
15042 // Content-Length: 0
15043 // Keep-Alive: timeout=2, max=100
15044 // Connection: Keep-Alive
15045 // Content-Type: text/plain
15046 //
15047
15048 const std::string origin_header = find_header_mg(msg, "Origin");
15049
15050 if (trace_mg||verbose_mg)
15051 printf("handle_http_options_cors: origin [%s]\n", origin_header.c_str());
15052
15053 std::string headers;
15054 headers += "HTTP/1.1 200 OK\n";
15055 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
15056 if (origin_header.length() > 0)
15057 headers += "Access-Control-Allow-Origin: " + origin_header + "\n";
15058 else
15059 headers += "Access-Control-Allow-Origin: *\n";
15060 headers += "Access-Control-Allow-Headers: Content-Type\n";
15061 headers += "Access-Control-Allow-Credentials: true\n";
15062 headers += "Access-Control-Max-Age: 120\n";
15063 headers += "Content-Length: 0\n";
15064 headers += "Content-Type: text/plain\n";
15065 //printf("sending headers: %s\n", headers.c_str());
15066 //printf("sending reply: %s\n", reply.c_str());
15067
15068 std::string send = headers + "\n";
15069
15071
15072 mg_send(nc, send.c_str(), send.length());
15073
15074 t->fTimeSent = GetTimeSec();
15075}
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 14889 of file mhttpd.cxx.

14890{
14891 std::string query_string = mgstr(&msg->query_string);
14892 std::string post_data = mgstr(&msg->body);
14893
14894 if (trace_mg||verbose_mg)
14895 printf("handle_http_post: uri [%s], query [%s], post data %d bytes\n", uri, query_string.c_str(), (int)post_data.length());
14896 if (trace_mg_verbose)
14897 printf("handle_http_post: post data = \n%s\n", post_data.c_str());
14898
14899 if (query_string.substr(0, 8) == "mjsonrpc") { // ignore any parameter after "mjsonrpc"
14900 const std::string origin_header = find_header_mg(msg, "Origin");
14901 const std::string ctype_header = find_header_mg(msg, "Content-Type");
14902
14903 if (strstr(ctype_header.c_str(), "application/json") == NULL) {
14904 std::string headers;
14905 headers += "HTTP/1.1 415 Unsupported Media Type\n";
14906 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14907
14908 //printf("sending headers: %s\n", headers.c_str());
14909 //printf("sending reply: %s\n", reply.c_str());
14910
14911 if (trace_mg_verbose)
14912 printf("handle_http_post: unsupported media type \"%s\"\n", ctype_header.c_str());
14913
14914 std::string send = headers + "\n";
14915
14917
14918 mg_send(nc, send.c_str(), send.length());
14919
14920 t->fTimeSent = GetTimeSec();
14921
14922 return RESPONSE_SENT;
14923 }
14924
14925#ifdef HAVE_MONGOOSE616
14926 if (multithread_mg)
14927 return queue_mjsonrpc(nc, origin_header, post_data, t);
14928#endif
14929
14930 //printf("post body: %s\n", post_data.c_str());
14931
14932 t->fRPC = post_data;
14933
14934#ifdef HAVE_MONGOOSE6
14935 int status = ss_mutex_wait_for(request_mutex, 0);
14936 assert(status == SS_SUCCESS);
14937#endif
14938
14939 //t->fTimeLocked = GetTimeSec();
14940
14941 MJsonNode* reply = mjsonrpc_decode_post_data(post_data.c_str());
14942
14943 //t->fTimeUnlocked = GetTimeSec();
14944
14945#ifdef HAVE_MONGOOSE6
14946 ss_mutex_release(request_mutex);
14947#endif
14948
14949 if (reply->GetType() == MJSON_ARRAYBUFFER) {
14950 const char* ptr;
14951 size_t size;
14952 reply->GetArrayBuffer(&ptr, &size);
14953
14954 std::string headers;
14955 headers += "HTTP/1.1 200 OK\n";
14956 if (origin_header.length() > 0)
14957 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14958 else
14959 headers += "Access-Control-Allow-Origin: *\n";
14960 headers += "Access-Control-Allow-Credentials: true\n";
14961 headers += "Content-Length: " + toString(size) + "\n";
14962 headers += "Content-Type: application/octet-stream\n";
14963 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14964
14965 //printf("sending headers: %s\n", headers.c_str());
14966 //printf("sending reply: %s\n", reply_string.c_str());
14967
14968 std::string send = headers + "\n";
14969
14971
14972 mg_send(nc, send.c_str(), send.length());
14973 mg_send(nc, ptr, size);
14974
14975 t->fTimeSent = GetTimeSec();
14976
14977 delete reply;
14978
14979 return RESPONSE_SENT;
14980 }
14981
14982 std::string reply_string = reply->Stringify();
14983 int reply_length = reply_string.length();
14984
14985 std::string headers;
14986 headers += "HTTP/1.1 200 OK\n";
14987 if (origin_header.length() > 0)
14988 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14989 else
14990 headers += "Access-Control-Allow-Origin: *\n";
14991 headers += "Access-Control-Allow-Credentials: true\n";
14992 headers += "Content-Length: " + toString(reply_length) + "\n";
14993 headers += "Content-Type: application/json\n";
14994 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14995
14996 //printf("sending headers: %s\n", headers.c_str());
14997 //printf("sending reply: %s\n", reply_string.c_str());
14998
14999 std::string send = headers + "\n" + reply_string;
15000
15002
15003 mg_send(nc, send.c_str(), send.length());
15004
15005 t->fTimeSent = GetTimeSec();
15006
15007 delete reply;
15008
15009 return RESPONSE_SENT;
15010 }
15011
15012 return handle_decode_post(nc, msg, uri, query_string.c_str(), t);
15013}
std::string fRPC
Definition mhttpd.cxx:397
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:14733
static bool trace_mg_verbose
Definition mhttpd.cxx:13713
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 7638 of file mhttpd.cxx.

7641{
7642 double dx, int_dx, frac_dx, x_act, label_dx, major_dx, x_screen, maxwidth;
7643 int tick_base, major_base, label_base, n_sig1, n_sig2, xs;
7644 char str[80];
7645 double base[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
7646
7647 if (xmax <= xmin || width <= 0)
7648 return;
7649
7650 /* use 5 as min tick distance */
7651 dx = (xmax - xmin) / (double) (width / 5);
7652
7653 frac_dx = modf(log(dx) / LN10, &int_dx);
7654 if (frac_dx < 0) {
7655 frac_dx += 1;
7656 int_dx -= 1;
7657 }
7658
7659 tick_base = frac_dx < LOG2 ? 1 : frac_dx < LOG5 ? 2 : 3;
7660 major_base = label_base = tick_base + 1;
7661
7662 /* rounding up of dx, label_dx */
7663 dx = pow(10, int_dx) * base[tick_base];
7664 major_dx = pow(10, int_dx) * base[major_base];
7665 label_dx = major_dx;
7666
7667 /* number of significant digits */
7668 if (xmin == 0)
7669 n_sig1 = 0;
7670 else
7671 n_sig1 = (int) floor(log(fabs(xmin)) / LN10) - (int) floor(log(fabs(label_dx)) / LN10) + 1;
7672
7673 if (xmax == 0)
7674 n_sig2 = 0;
7675 else
7676 n_sig2 =
7677 (int) floor(log(fabs(xmax)) / LN10) - (int) floor(log(fabs(label_dx)) / LN10) + 1;
7678
7679 n_sig1 = MAX(n_sig1, n_sig2);
7680 n_sig1 = MAX(n_sig1, 4);
7681
7682 /* determination of maximal width of labels */
7683 sprintf(str, "%1.*lG", n_sig1, floor(xmin / dx) * dx);
7684 maxwidth = font->h / 2 * strlen(str);
7685 sprintf(str, "%1.*lG", n_sig1, floor(xmax / dx) * dx);
7686 maxwidth = MAX(maxwidth, font->h / 2 * strlen(str));
7687 sprintf(str, "%1.*lG", n_sig1, floor(xmax / dx) * dx + label_dx);
7688 maxwidth = MAX(maxwidth, font->h / 2 * strlen(str));
7689
7690 /* increasing label_dx, if labels would overlap */
7691 while (maxwidth > 0.7 * label_dx / (xmax - xmin) * width) {
7692 label_base++;
7693 label_dx = pow(10, int_dx) * base[label_base];
7694 if (label_base % 3 == 2 && major_base % 3 == 1) {
7695 major_base++;
7696 major_dx = pow(10, int_dx) * base[major_base];
7697 }
7698 }
7699
7700 x_act = floor(xmin / dx) * dx;
7701
7702 gdImageLine(im, x1, y1, x1 + width, y1, col);
7703
7704 do {
7705 x_screen = (x_act - xmin) / (xmax - xmin) * width + x1;
7706 xs = (int) (x_screen + 0.5);
7707
7708 if (x_screen > x1 + width + 0.001)
7709 break;
7710
7711 if (x_screen >= x1) {
7712 if (fabs(floor(x_act / major_dx + 0.5) - x_act / major_dx) <
7713 dx / major_dx / 10.0) {
7714
7715 if (fabs(floor(x_act / label_dx + 0.5) - x_act / label_dx) <
7716 dx / label_dx / 10.0) {
7717 /* label tick mark */
7718 gdImageLine(im, xs, y1, xs, y1 + text, col);
7719
7720 /* grid line */
7721 if (grid != 0 && xs > x1 && xs < x1 + width)
7722 gdImageLine(im, xs, y1, xs, y1 + grid, col);
7723
7724 /* label */
7725 if (label != 0) {
7726 sprintf(str, "%1.*lG", n_sig1, x_act);
7727 gdImageString(im, font, (int) xs - font->w * strlen(str) / 2,
7728 y1 + label, str, col);
7729 }
7730 } else {
7731 /* major tick mark */
7732 gdImageLine(im, xs, y1, xs, y1 + major, col);
7733
7734 /* grid line */
7735 if (grid != 0 && xs > x1 && xs < x1 + width)
7736 gdImageLine(im, xs, y1 - 1, xs, y1 + grid, gcol);
7737 }
7738
7739 } else
7740 /* minor tick mark */
7741 gdImageLine(im, xs, y1, xs, y1 + minor, col);
7742
7743 }
7744
7745 x_act += dx;
7746
7747 /* supress 1.23E-17 ... */
7748 if (fabs(x_act) < dx / 100)
7749 x_act = 0;
7750
7751 } while (1);
7752}
#define MAX(a, b)
Definition midas.h:509
#define LOG2
Definition mhttpd.cxx:7635
#define LOG5
Definition mhttpd.cxx:7636
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 8151 of file mhttpd.cxx.

8152{
8153 //printf("history_watch_callback %d %d %d\n", hDB, hKey, index);
8154 gDoReloadHistory = true;
8155 cm_msg(MINFO, "history_watch_callback", "History configuration may have changed, will reconnect");
8156}
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 1981 of file mhttpd.cxx.

1982{
1983 HNDLE hDB;
1984 int size;
1985 HNDLE hkey;
1987
1988 BOOL external_elog = FALSE;
1989 std::string external_elog_url;
1990
1991 size = sizeof(external_elog);
1992 db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
1993 db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
1994
1995 BOOL allow_delete = FALSE;
1996 BOOL allow_edit = FALSE;
1997 size = sizeof(BOOL);
1998 db_get_value(hDB, 0, "/Elog/Allow delete", &allow_delete, &size, TID_BOOL, TRUE);
1999 db_get_value(hDB, 0, "/Elog/Allow edit", &allow_edit, &size, TID_BOOL, TRUE);
2000 //db_get_value(hDB, 0, "/Elog/Display run number", &display_run_number, &size, TID_BOOL, TRUE);
2001
2002 if (db_find_key(hDB, 0, "/Elog/Buttons", &hkey) != DB_SUCCESS) {
2003 const char def_button[][NAME_LENGTH] = { "8h", "24h", "7d" };
2004 db_set_value(hDB, 0, "/Elog/Buttons", def_button, NAME_LENGTH*3, 3, TID_STRING);
2005 }
2006
2007
2008 /* get type list from ODB */
2009 size = 20 * NAME_LENGTH;
2010 if (db_find_key(hDB, 0, "/Elog/Types", &hkey) != DB_SUCCESS) {
2011 db_set_value(hDB, 0, "/Elog/Types", default_type_list, NAME_LENGTH * 20, 20, TID_STRING);
2012 }
2013
2014 /* get system list from ODB */
2015 size = 20 * NAME_LENGTH;
2016 if (db_find_key(hDB, 0, "/Elog/Systems", &hkey) != DB_SUCCESS)
2017 db_set_value(hDB, 0, "/Elog/Systems", default_system_list, NAME_LENGTH * 20, 20, TID_STRING);
2018}
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 1892 of file mhttpd.cxx.

1893{
1894 HNDLE hDB;
1895 BOOL true_value = TRUE;
1896 BOOL false_value = FALSE;
1897 int size = sizeof(true_value);
1899 db_get_value(hDB, 0, "/Experiment/Menu/Status", &true_value, &size, TID_BOOL, TRUE);
1900 db_get_value(hDB, 0, "/Experiment/Menu/Start", &false_value, &size, TID_BOOL, TRUE);
1901 db_get_value(hDB, 0, "/Experiment/Menu/Transition", &true_value, &size, TID_BOOL, TRUE);
1902 db_get_value(hDB, 0, "/Experiment/Menu/ODB", &true_value, &size, TID_BOOL, TRUE);
1903 db_get_value(hDB, 0, "/Experiment/Menu/OldODB", &true_value, &size, TID_BOOL, TRUE);
1904 db_get_value(hDB, 0, "/Experiment/Menu/Messages", &true_value, &size, TID_BOOL, TRUE);
1905 db_get_value(hDB, 0, "/Experiment/Menu/Chat", &true_value, &size, TID_BOOL, TRUE);
1906 db_get_value(hDB, 0, "/Experiment/Menu/Elog", &true_value, &size, TID_BOOL, TRUE);
1907 db_get_value(hDB, 0, "/Experiment/Menu/Alarms", &true_value, &size, TID_BOOL, TRUE);
1908 db_get_value(hDB, 0, "/Experiment/Menu/Programs", &true_value, &size, TID_BOOL, TRUE);
1909 db_get_value(hDB, 0, "/Experiment/Menu/Buffers", &true_value, &size, TID_BOOL, TRUE);
1910 db_get_value(hDB, 0, "/Experiment/Menu/History", &true_value, &size, TID_BOOL, TRUE);
1911 db_get_value(hDB, 0, "/Experiment/Menu/OldHistory", &true_value, &size, TID_BOOL, TRUE);
1912 db_get_value(hDB, 0, "/Experiment/Menu/MSCB", &true_value, &size, TID_BOOL, TRUE);
1913 db_get_value(hDB, 0, "/Experiment/Menu/Sequencer", &true_value, &size, TID_BOOL, TRUE);
1914 db_get_value(hDB, 0, "/Experiment/Menu/PySequencer",&true_value, &size, TID_BOOL, TRUE);
1915 db_get_value(hDB, 0, "/Experiment/Menu/Event Dump", &true_value, &size, TID_BOOL, TRUE);
1916 db_get_value(hDB, 0, "/Experiment/Menu/Config", &true_value, &size, TID_BOOL, TRUE);
1917 db_get_value(hDB, 0, "/Experiment/Menu/Example", &false_value, &size, TID_BOOL, TRUE);
1918 db_get_value(hDB, 0, "/Experiment/Menu/Help", &true_value, &size, TID_BOOL, TRUE);
1919
1920 //std::string buf;
1921 //status = db_get_value_string(hDB, 0, "/Experiment/Menu buttons", 0, &buf, FALSE);
1922 //if (status == DB_SUCCESS) {
1923 // cm_msg(MERROR, "init_menu_buttons", "ODB \"/Experiment/Menu buttons\" is obsolete, please delete it.");
1924 //}
1925
1926 check_obsolete_odb(hDB, "/Experiment/Menu buttons");
1927 check_obsolete_odb(hDB, "/Experiment/Menu/OldSequencer");
1928 check_obsolete_odb(hDB, "/Experiment/Menu/NewSequencer");
1929}
void check_obsolete_odb(HNDLE hDB, const char *odb_path)
Definition mhttpd.cxx:1883
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 1933 of file mhttpd.cxx.

1934{
1935 HNDLE hDB;
1936 HNDLE hKey;
1937 int status;
1938 std::string s;
1940
1941 status = db_find_key(hDB, 0, "/Experiment/Base URL", &hKey);
1942 if (status == DB_SUCCESS) {
1943 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Base URL\" is obsolete, please delete it.");
1944 }
1945
1946 status = db_find_key(hDB, 0, "/Experiment/CSS File", &hKey);
1947 if (status == DB_SUCCESS) {
1948 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/CSS File\" is obsolete, please delete it.");
1949 }
1950
1951 status = db_find_key(hDB, 0, "/Experiment/JS File", &hKey);
1952 if (status == DB_SUCCESS) {
1953 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/JS File\" is obsolete, please delete it.");
1954 }
1955
1956 status = db_find_key(hDB, 0, "/Experiment/Start-Stop Buttons", &hKey);
1957 if (status == DB_SUCCESS) {
1958 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Start-Stop Buttons\" is obsolete, please delete it.");
1959 }
1960
1961 bool xdefault = true;
1962 odb->RB("Experiment/Pause-Resume Buttons", &xdefault, true);
1963
1964#ifdef HAVE_MONGOOSE616
1965 check_obsolete_odb(hDB, "/Experiment/midas http port");
1966 check_obsolete_odb(hDB, "/Experiment/midas https port");
1967 check_obsolete_odb(hDB, "/Experiment/http redirect to https");
1968 check_obsolete_odb(hDB, "/Experiment/Security/mhttpd hosts");
1969#endif
1970
1971 status = db_find_key(hDB, 0, "/Logger/Message file", &hKey);
1972 if (status == DB_SUCCESS) {
1973 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.");
1974 }
1975
1976 check_obsolete_odb(hDB, "/Logger/Watchdog timeout");
1977}
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 12256 of file mhttpd.cxx.

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

2535{
2536 HNDLE hDB, hkey;
2537 KEY key;
2538 char str[256];
2539 int i, size;
2540
2542 sprintf(str, "/Equipment/%s/Settings/Editable", eq_name);
2543 db_find_key(hDB, 0, str, &hkey);
2544
2545 /* if no editable entry found, use default */
2546 if (!hkey) {
2547 return (equal_ustring(var_name, "Demand") ||
2548 equal_ustring(var_name, "Output") || strncmp(var_name, "D_", 2) == 0);
2549 }
2550
2551 db_get_key(hDB, hkey, &key);
2552 for (i = 0; i < key.num_values; i++) {
2553 size = sizeof(str);
2554 db_get_data_index(hDB, hkey, str, &size, i, TID_STRING);
2556 return TRUE;
2557 }
2558 return FALSE;
2559}
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 4454 of file mhttpd.cxx.

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

10202{
10203 std::string path = "History/Display/";
10204 path += group;
10205 path += "/";
10206 path += panel;
10207
10208 MVOdb* o = odb->Chdir(path.c_str());
10209 if (!o) {
10210 return;
10211 }
10212
10213 o->RS("Timescale", &hp->timescale);
10214 o->RD("Minimum", &hp->minimum);
10215 o->RD("Maximum", &hp->maximum);
10216 o->RB("Zero ylow", &hp->zero_ylow);
10217 o->RB("Log axis", &hp->log_axis);
10218 o->RB("Zero ylow", &hp->zero_ylow);
10219 o->RB("Show run markers", &hp->show_run_markers);
10220 o->RB("Show values", &hp->show_values);
10221 o->RB("Show fill", &hp->show_fill);
10222 o->RB("Show factor", &hp->show_factor);
10223 //o->RB("Enable factor and offset", &hp->enable_factor);
10224
10225 std::vector<std::string> hist_vars;
10226 std::vector<std::string> hist_formula;
10227 std::vector<std::string> hist_colour;
10228 std::vector<std::string> hist_label;
10229 std::vector<bool> hist_show_raw_value;
10230 std::vector<double> hist_factor;
10231 std::vector<double> hist_offset;
10232 std::vector<double> hist_voffset;
10233
10234 o->RSA("Variables", &hist_vars);
10235 o->RSA("Formula", &hist_formula);
10236 o->RSA("Colour", &hist_colour);
10237 o->RSA("Label", &hist_label);
10238 o->RBA("Show raw value", &hist_show_raw_value);
10239 o->RDA("Factor", &hist_factor);
10240 o->RDA("Offset", &hist_offset);
10241 o->RDA("VOffset", &hist_voffset);
10242
10243 // fix broken plots with "factor" all zero. for reasons
10244 // unknown the new history code has corrupted many
10245 // history plot definitions like this. K.O.
10246 {
10247 bool all_zero = true;
10248 for (size_t i=0; i<hist_factor.size(); i++) {
10249 if (hist_factor[i] != 0)
10250 all_zero = false;
10251 }
10252 if (all_zero) {
10253 for (size_t i=0; i<hist_factor.size(); i++) {
10254 hist_factor[i] = 1.0;
10255 }
10256 }
10257 }
10258
10259 size_t num = std::max(hist_vars.size(), hist_formula.size());
10260 num = std::max(num, hist_colour.size());
10261 num = std::max(num, hist_label.size());
10262 num = std::max(num, hist_show_raw_value.size());
10263 num = std::max(num, hist_factor.size());
10264 num = std::max(num, hist_offset.size());
10265 num = std::max(num, hist_voffset.size());
10266
10267 hist_vars.resize(num);
10268 hist_formula.resize(num);
10269 hist_colour.resize(num);
10270 hist_label.resize(num);
10271 hist_show_raw_value.resize(num);
10272 hist_factor.resize(num, 1.0);
10273 hist_offset.resize(num, 0.0);
10274 hist_voffset.resize(num, 0.0);
10275
10276 for (size_t i=0; i<num; i++) {
10277 HistVar v;
10278
10279 SplitEventAndTagNames(hist_vars[i], v.event_name, v.tag_name);
10280
10281 v.formula = hist_formula[i];
10282 v.colour = hist_colour[i];
10283 v.label = hist_label[i];
10284 v.show_raw_value = hist_show_raw_value[i];
10285 v.factor = hist_factor[i];
10286 v.offset = hist_offset[i];
10287 v.voffset = hist_voffset[i];
10288 v.order = NextHistPlotOrder(*hp);
10289
10290 // one-time migration of factor and offset to formula
10291 if (hp->enable_factor && v.formula.empty()) {
10292 if (v.factor!=1 || v.offset!=0 || v.voffset!=0) {
10293 v.formula = msprintf("%g%+g*(x%+g)", v.offset, v.factor, -v.voffset);
10294 }
10295 }
10296
10297 hp->vars.push_back(v);
10298 }
10299
10300// printf("Load from ODB %s: ", path.c_str());
10301// PrintHistPlot(*hp);
10302
10303 delete o;
10304}
bool show_fill
Definition mhttpd.cxx:8353
bool show_factor
Definition mhttpd.cxx:8354
double factor
Definition mhttpd.cxx:8339
double offset
Definition mhttpd.cxx:8340
std::string formula
Definition mhttpd.cxx:8334
std::string label
Definition mhttpd.cxx:8336
double voffset
Definition mhttpd.cxx:8341
bool show_raw_value
Definition mhttpd.cxx:8337
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 10306 of file mhttpd.cxx.

10307{
10308 hp->timescale = p->getparam("timescale");
10309 hp->minimum = strtod(p->getparam("minimum"), NULL);
10310 hp->maximum = strtod(p->getparam("maximum"), NULL);
10311 hp->zero_ylow = *p->getparam("zero_ylow");
10312 hp->log_axis = *p->getparam("log_axis");
10313 hp->show_run_markers = *p->getparam("run_markers");
10314 hp->show_values = *p->getparam("show_values");
10315 hp->show_fill = *p->getparam("show_fill");
10316 hp->show_factor = *p->getparam("show_factor");
10317 //hp->enable_factor = *p->getparam("enable_factor");
10318
10319 for (int index=0; ; index++) {
10320 char str[256];
10321 sprintf(str, "event%d", index);
10322
10323 //printf("param event %d: [%s] [%s] [%d]\n", index, str, p->getparam(str), *p->getparam(str));
10324
10325 if (!p->isparam(str))
10326 break;
10327
10328 if (*p->getparam(str) == '/') // "/empty"
10329 continue;
10330
10331 HistVar v;
10332
10333 v.event_name = p->xgetparam(str);
10334
10335 sprintf(str, "var%d", index);
10336 v.tag_name = p->xgetparam(str);
10337
10338 sprintf(str, "form%d", index);
10339 v.formula = p->xgetparam(str);
10340
10341 sprintf(str, "col%d", index);
10342 v.colour = p->xgetparam(str);
10343
10344 sprintf(str, "lab%d", index);
10345 v.label = p->xgetparam(str);
10346
10347 sprintf(str, "raw%d", index);
10348 v.show_raw_value = atoi(p->xgetparam(str).c_str());
10349
10350 sprintf(str, "factor%d", index);
10351 if (p->isparam(str)) {
10352 v.factor = atof(p->xgetparam(str).c_str());
10353 } else {
10354 v.factor = 1.0;
10355 }
10356
10357 sprintf(str, "offset%d", index);
10358 v.offset = atof(p->xgetparam(str).c_str());
10359
10360 sprintf(str, "voffset%d", index);
10361 v.voffset = atof(p->xgetparam(str).c_str());
10362
10363 sprintf(str, "ord%d", index);
10364 if (p->isparam(str)) {
10365 v.order = atoi(p->xgetparam(str).c_str());
10366 } else {
10367 v.order = NextHistPlotOrder(*hp);
10368 }
10369
10370 hp->vars.push_back(v);
10371 }
10372
10373 /* correctly number newly added variables */
10374 for (size_t index=0; index<hp->vars.size(); index++) {
10375 if (hp->vars[index].order < 0)
10376 hp->vars[index].order = NextHistPlotOrder(*hp);
10377 }
10378
10379// printf("Load from param:\n");
10380// PrintHistPlot(*hp);
10381}
std::string xgetparam(const char *param)
Definition mhttpd.cxx:796
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Lock()

void Lock ( RequestTrace t)

Definition at line 12242 of file mhttpd.cxx.

12243{
12244 gMutex.lock();
12245 t->fTimeLocked = GetTimeSec();
12246}
double fTimeLocked
Definition mhttpd.cxx:389
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 16224 of file mhttpd.cxx.

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

14143{
14144 return std::string(s->p, s->len);
14145}
Here is the caller graph for this function:

◆ mhttpd_revision()

const char * mhttpd_revision ( void  )

Definition at line 836 of file mhttpd.cxx.

837{
838 return cm_get_revision();
839}
const char * cm_get_revision()
Definition midas.cxx:1499
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 9751 of file mhttpd.cxx.

9752{
9753 // this silly stuff is required to correctly handle daylight savings time (Summer time/Winter time)
9754 // when we fill "struct tm" from user input, we cannot know if daylight savings time is in effect
9755 // and we do not know how to initialize the value of tms.tm_isdst.
9756 // This can cause the output of mktime() to be off by one hour.
9757 // (Rules for daylight savings time are set by national and local govt and in some locations, changes yearly)
9758 // (There are no locations with 2 hour or half-hour daylight savings that I know of)
9759 // (Yes, "man mktime" talks about using "tms.tm_isdst = -1")
9760 //
9761 // We assume the user is using local time and we convert in two steps:
9762 //
9763 // first we convert "struct tm" to "time_t" using mktime() with unknown tm_isdst
9764 // second we convert "time_t" back to "struct tm" using localtime_r()
9765 // this fills "tm_isdst" with correct value from the system time zone database
9766 // then we reset all the time fields (except for sub-minute fields not affected by daylight savings)
9767 // and call mktime() again, now with the correct value of "tm_isdst".
9768 // K.O. 2013-09-14
9769
9770 struct tm tms = *ptms;
9771 struct tm tms2;
9772 time_t t1 = ss_mktime(&tms);
9773 localtime_r(&t1, &tms2);
9774 tms2.tm_year = ptms->tm_year;
9775 tms2.tm_mon = ptms->tm_mon;
9776 tms2.tm_mday = ptms->tm_mday;
9777 tms2.tm_hour = ptms->tm_hour;
9778 tms2.tm_min = ptms->tm_min;
9779 time_t t2 = ss_mktime(&tms2);
9780 //printf("t1 %.0f, t2 %.0f, diff %d\n", (double)t1, (double)t2, (int)(t1-t2));
9781 return t2;
9782}
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 10122 of file mhttpd.cxx.

10123{
10124 const char* const colour[] =
10125 {
10126 "#00AAFF", "#FF9000", "#FF00A0", "#00C030",
10127 "#A0C0D0", "#D0A060", "#C04010", "#807060",
10128 "#F0C000", "#2090A0", "#D040D0", "#90B000",
10129 "#B0B040", "#B0B0FF", "#FFA0A0", "#A0FFA0",
10130 NULL };
10131
10132 for (int i=0; colour[i]; i++) {
10133 bool in_use = false;
10134
10135 for (size_t j=0; j<hp.vars.size(); j++)
10136 if (hp.vars[j].colour == colour[i]) {
10137 in_use = true;
10138 break;
10139 }
10140
10141 if (!in_use)
10142 return colour[i];
10143 }
10144
10145 return "#808080";
10146}
Here is the caller graph for this function:

◆ NextHistPlotOrder()

static int NextHistPlotOrder ( const HistPlot hp)
static

Definition at line 10148 of file mhttpd.cxx.

10149{
10150 int order = 0;
10151 for (size_t i=0; i<hp.vars.size(); i++)
10152 if (hp.vars[i].order > order)
10153 order = hp.vars[i].order;
10154 return order + 10;
10155}
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 1031 of file mhttpd.cxx.

1032{
1033 // resource file names should not start with a directory separator "/"
1034 // or contain ".." as this will allow them to escape the mhttpd filename "jail"
1035 // by asking file files names like "../../etc/passwd", etc.
1036
1037 if (strlen(filename) < 1) {
1038 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' is too short",
1039 filename);
1040 return false;
1041 }
1042
1043 if (filename[0] == DIR_SEPARATOR) {
1044 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' starting with \'%c\' which is not allowed",
1045 filename, DIR_SEPARATOR);
1046 return false;
1047 }
1048
1049 if (strstr(filename, "..") != NULL) {
1050 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' containing \'..\' which is not allowed",
1051 filename);
1052 return false;
1053 }
1054
1055 std::vector<std::string> paths = get_resource_paths();
1056
1057 std::vector<std::string> paths_not_found;
1058
1059 for (unsigned i=0; i<paths.size(); i++) {
1060 std::string path = paths[i];
1061 if (path.length() < 1)
1062 continue;
1063 if (path[0] == '#')
1064 continue;
1065
1066 // expand env.variables before we add the filename.
1067 // the filename comes from the URL and if the URL
1068 // has '$' characters we will try to expand them
1069 // as an env.variable and maybe escape the file jail.
1070
1071 std::string xpath = cm_expand_env(path.c_str());
1072
1073 if (xpath[xpath.length()-1] != DIR_SEPARATOR)
1074 xpath += DIR_SEPARATOR_STR;
1075 xpath += filename;
1076
1077 //printf("path [%s] [%s] [%s]\n", paths[i].c_str(), path.c_str(), xpath.c_str());
1078
1079 FILE* fp = fopen(xpath.c_str(), "r");
1080 if (fp) {
1081 struct stat statbuf;
1082 int status = fstat(fileno(fp), &statbuf);
1083 if (status != 0) {
1084 cm_msg(MERROR, "open_resource_file", "Cannot fstat() file \'%s\', error %d (%s)", xpath.c_str(), errno, strerror(errno));
1085 fclose(fp);
1086 fp = NULL;
1087 }
1088
1089 if (statbuf.st_mode & S_IFREG) {
1090 // good, normal file
1091 //printf("%s: regular!\n", xpath.c_str());
1092 //} else if (statbuf.st_mode & S_IFLNK) {
1093 // symlink
1094 //printf("%s: symlink!\n", xpath.c_str());
1095 } else if (statbuf.st_mode & S_IFDIR) {
1096 cm_msg(MERROR, "open_resource_file", "File \'%s\' for resource \'%s\' is a directory", xpath.c_str(), filename);
1097 fclose(fp);
1098 fp = NULL;
1099 } else {
1100 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);
1101 fclose(fp);
1102 fp = NULL;
1103 }
1104
1105 if (fp) {
1106 if (ppath)
1107 *ppath = xpath;
1108 if (pfp) {
1109 *pfp = fp;
1110 } else {
1111 fclose(fp);
1112 fp = NULL;
1113 }
1114 //cm_msg(MINFO, "open_resource_file", "Resource file \'%s\' is \'%s\'", filename, xpath.c_str());
1115 return true;
1116 }
1117 }
1118
1119 paths_not_found.push_back(xpath);
1120 }
1121
1122 std::string s;
1123 for (unsigned i=0; i<paths_not_found.size(); i++) {
1124 if (i>0)
1125 s += ", ";
1126 s += paths_not_found[i];
1127 }
1128
1129 cm_msg(MERROR, "open_resource_file", "Cannot find resource file \'%s\', tried %s", filename, s.c_str());
1130 return false;
1131}
std::string cm_expand_env(const char *str)
Definition midas.cxx:7720
std::vector< std::string > get_resource_paths()
Definition mhttpd.cxx:991
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 4379 of file mhttpd.cxx.

4380{
4381 int size, i;
4382 HNDLE hDB, hsubkey;
4383 KEY key;
4384 char data[TEXT_SIZE];
4385
4387
4388 db_get_key(hDB, hkey, &key);
4389 if (key.type == TID_KEY) {
4390 for (i=0 ; ; i++) {
4391 db_enum_key(hDB, hkey, i, &hsubkey);
4392 if (!hsubkey)
4393 break;
4394 output_key(p, r, hsubkey, -1, format);
4395 }
4396 } else {
4397 if (key.item_size <= (int)sizeof(data)) {
4398 size = sizeof(data);
4399 db_get_data(hDB, hkey, data, &size, key.type);
4400 if (index == -1) {
4401 for (i=0 ; i<key.num_values ; i++) {
4402 if (p->isparam("name") && atoi(p->getparam("name")) == 1) {
4403 if (key.num_values == 1)
4404 r->rsprintf("%s:", key.name);
4405 else
4406 r->rsprintf("%s[%d]:", key.name, i);
4407 }
4408 std::string data_str;
4409 if (format && format[0])
4410 data_str = db_sprintff(format, data, key.item_size, i, key.type);
4411 else
4412 data_str = db_sprintf(data, key.item_size, i, key.type);
4413 r->rsputs(data_str.c_str());
4414 if (i<key.num_values-1)
4415 r->rsputs("\n");
4416 }
4417 } else {
4418 if (p->isparam("name") && atoi(p->getparam("name")) == 1)
4419 r->rsprintf("%s[%d]:", key.name, index);
4420 if (index >= key.num_values)
4421 r->rsputs("<DB_OUT_OF_RANGE>");
4422 else {
4423 std::string data_str;
4424 if (p->isparam("format"))
4425 data_str = db_sprintff(p->getparam("format"), data, key.item_size, index, key.type);
4426 else
4427 data_str = db_sprintf(data, key.item_size, index, key.type);
4428 r->rsputs(data_str.c_str());
4429 }
4430 }
4431 r->rsputs("\n");
4432 }
4433 }
4434}
INT db_sprintff(char *string, const char *format, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10688
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 10112 of file mhttpd.cxx.

10113{
10114 printf("hist plot: %d variables\n", (int)hp.vars.size());
10115 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);
10116
10117 for (size_t i=0; i<hp.vars.size(); i++) {
10118 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);
10119 }
10120}

◆ 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 8362 of file mhttpd.cxx.

8363{
8364 //HNDLE hkeypanel, hkeydvar, hkey;
8365 //KEY key;
8366 //char path[256];
8367 //int n_vars;
8368 int status;
8369 int debug = 1;
8370
8371 //mstrlcpy(path, group, sizeof(path));
8372 //mstrlcat(path, "/", sizeof(path));
8373 //mstrlcat(path, panel, sizeof(path));
8374
8375 //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);
8376
8377 /* connect to history */
8379 if (mh == NULL) {
8380 //r->rsprintf(str, "History is not configured\n");
8381 return HS_FILE_ERROR;
8382 }
8383
8384#if 0
8385 /* check panel name in ODB */
8386 status = db_find_key(hDB, 0, "/History/Display", &hkey);
8387 if (!hkey) {
8388 cm_msg(MERROR, "read_history", "Cannot find \'/History/Display\' in ODB, status %d", status);
8389 return HS_FILE_ERROR;
8390 }
8391
8392 /* check panel name in ODB */
8393 status = db_find_key(hDB, hkey, path, &hkeypanel);
8394 if (!hkeypanel) {
8395 cm_msg(MERROR, "read_history", "Cannot find \'%s\' in ODB, status %d", path, status);
8396 return HS_FILE_ERROR;
8397 }
8398
8399 status = db_find_key(hDB, hkeypanel, "Variables", &hkeydvar);
8400 if (!hkeydvar) {
8401 cm_msg(MERROR, "read_history", "Cannot find \'%s/Variables\' in ODB, status %d", path, status);
8402 return HS_FILE_ERROR;
8403 }
8404
8405 db_get_key(hDB, hkeydvar, &key);
8406 n_vars = key.num_values;
8407#endif
8408
8409 data->Allocate(hp.vars.size()+2);
8410
8411 data->tstart = tstart;
8412 data->tend = tend;
8413 data->scale = scale;
8414
8415 for (size_t i=0; i<hp.vars.size(); i++) {
8416 if (index != -1 && (size_t)index != i)
8417 continue;
8418
8419 //char str[256];
8420 //int size = sizeof(str);
8421 //status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
8422 //if (status != DB_SUCCESS) {
8423 // cm_msg(MERROR, "read_history", "Cannot read tag %d in panel %s, status %d", i, path, status);
8424 // continue;
8425 //}
8426
8427 /* split varname in event, variable and index: "event/tag[index]" */
8428
8429 //char *p = strchr(str, ':');
8430 //if (!p)
8431 // p = strchr(str, '/');
8432 //
8433 //if (!p) {
8434 // cm_msg(MERROR, "read_history", "Tag \"%s\" has wrong format in panel \"%s\"", str, path);
8435 // continue;
8436 //}
8437
8438 //*p = 0;
8439
8440 data->odb_index[data->nvars] = i;
8441 data->event_names[data->nvars] = STRDUP(hp.vars[i].event_name.c_str());
8442 data->var_names[data->nvars] = STRDUP(hp.vars[i].tag_name.c_str());
8443 data->var_index[data->nvars] = 0;
8444
8445 char *q = strchr(data->var_names[data->nvars], '[');
8446 if (q) {
8447 data->var_index[data->nvars] = atoi(q+1);
8448 *q = 0;
8449 }
8450
8451 data->nvars++;
8452 } // loop over variables
8453
8454 /* write run markes if selected */
8455 if (flags & READ_HISTORY_RUNMARKER) {
8456
8457 data->event_names[data->nvars+0] = STRDUP("Run transitions");
8458 data->event_names[data->nvars+1] = STRDUP("Run transitions");
8459
8460 data->var_names[data->nvars+0] = STRDUP("State");
8461 data->var_names[data->nvars+1] = STRDUP("Run number");
8462
8463 data->var_index[data->nvars+0] = 0;
8464 data->var_index[data->nvars+1] = 0;
8465
8466 data->odb_index[data->nvars+0] = -1;
8467 data->odb_index[data->nvars+1] = -2;
8468
8469 data->nvars += 2;
8470 }
8471
8472 bool get_last_written = false;
8473
8474 if (flags & READ_HISTORY_DATA) {
8475 status = mh->hs_read(tstart, tend, scale,
8476 data->nvars,
8477 data->event_names,
8478 data->var_names,
8479 data->var_index,
8480 data->num_entries,
8481 data->t,
8482 data->v,
8483 data->status);
8484
8485 if (debug) {
8486 printf("read_history: nvars %d, hs_read() status %d\n", data->nvars, status);
8487 for (int i=0; i<data->nvars; i++) {
8488 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]);
8489 }
8490 }
8491
8492 if (status != HS_SUCCESS) {
8493 cm_msg(MERROR, "read_history", "Complete history failure, hs_read() status %d, see messages", status);
8494 return HS_FILE_ERROR;
8495 }
8496
8497 for (int i=0; i<data->nvars; i++) {
8498 if (data->status[i] != HS_SUCCESS || data->num_entries[i] < 1) {
8499 get_last_written = true;
8500 break;
8501 }
8502 }
8503 }
8504
8505 if (flags & READ_HISTORY_LAST_WRITTEN)
8506 get_last_written = true;
8507
8508 if (get_last_written) {
8509 data->have_last_written = true;
8510
8512 tstart,
8513 data->nvars,
8514 data->event_names,
8515 data->var_names,
8516 data->var_index,
8517 data->last_written);
8518
8519 if (status != HS_SUCCESS) {
8520 data->have_last_written = false;
8521 }
8522 }
8523
8524 return SUCCESS;
8525}
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:8243
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 13802 of file mhttpd.cxx.

13803{
13804 std::string path;
13805 FILE *fp;
13806 int status = find_file_mg("htpasswd.txt", path, &fp, trace_mg||verbose_mg);
13807
13808 auth->passwd_filename = path;
13809 auth->passwords.clear();
13810
13811 if (status != SUCCESS || fp == NULL) {
13812 cm_msg(MERROR, "mongoose", "mongoose web server cannot find password file \"%s\"", path.c_str());
13813 cm_msg(MERROR, "mongoose", "please create password file: touch %s", path.c_str());
13814 return false;
13815 }
13816
13817 bool have_realm = false;
13818 char buf[256];
13819
13820 /*
13821 * Read passwords file line by line. If should have htdigest format,
13822 * i.e. each line should be a colon-separated sequence:
13823 * USER_NAME:DOMAIN_NAME:HA1_HASH_OF_USER_DOMAIN_AND_PASSWORD
13824 */
13825 while (fgets(buf, sizeof(buf), fp) != NULL) {
13826 char f_user[256];
13827 char f_domain[256];
13828 char f_ha1[256];
13829
13830 if (sscanf(buf, "%[^:]:%[^:]:%s", f_user, f_domain, f_ha1) == 3) {
13831 AuthEntry e;
13832 e.realm = f_domain;
13833 e.username = f_user;
13834 e.password = f_ha1;
13835
13836 if (e.realm == auth->realm) {
13837 have_realm = true;
13838 auth->passwords.push_back(e);
13839 }
13840 }
13841 }
13842
13843 fclose(fp);
13844
13845 return have_realm;
13846}
std::string passwd_filename
Definition mhttpd.cxx:13731
int find_file_mg(const char *filename, std::string &path, FILE **fpp, bool trace)
Definition mhttpd.cxx:13677
std::string realm
Definition mhttpd.cxx:13724
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 1409 of file mhttpd.cxx.

1410{
1411 char str[256];
1412
1413 //printf("redirect to [%s]\n", path);
1414
1415 mstrlcpy(str, path, sizeof(str));
1416 if (str[0] == 0)
1417 strcpy(str, "./");
1418
1419 /* redirect */
1420 r->rsprintf("HTTP/1.1 302 Found\r\n");
1421 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1422 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1423
1424 if (strncmp(path, "http:", 5) == 0)
1425 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1426 else if (strncmp(path, "https:", 6) == 0)
1427 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1428 else {
1429 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1430 }
1431}
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 1446 of file mhttpd.cxx.

1447{
1448 redirect(r, path);
1449}
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 1433 of file mhttpd.cxx.

1434{
1435 //printf("redirect_307 to [%s]\n", path);
1436
1437 /* redirect */
1438 r->rsprintf("HTTP/1.1 307 Temporary Redirect\r\n");
1439 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1440 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1441 r->rsprintf("Location: %s\r\n", path);
1442 r->rsprintf("\r\n");
1443 r->rsprintf("<html>redirect to %s</html>\r\n", path);
1444}
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 10411 of file mhttpd.cxx.

10412{
10413 if (strlen(group) < 1) {
10414 cm_msg(MERROR, "SaveHistPlotToOdb", "Error: Cannot write history plot to ODB, group \"%s\", panel \"%s\", invalid group name", group, panel);
10415 return;
10416 }
10417
10418 if (strlen(panel) < 1) {
10419 cm_msg(MERROR, "SaveHistPlotToOdb", "Error: Cannot write history plot to ODB, group \"%s\", panel \"%s\", invalid panel name", group, panel);
10420 return;
10421 }
10422
10423 std::string path = "History/Display/";
10424 path += group;
10425 path += "/";
10426 path += panel;
10427
10428// printf("Save to ODB %s: ", path.c_str());
10429// PrintHistPlot(hp);
10430
10431 MVOdb* o = odb->Chdir(path.c_str(), true);
10432
10433 o->WS("Timescale", hp.timescale.c_str());
10434 o->WD("Minimum", hp.minimum);
10435 o->WD("Maximum", hp.maximum);
10436 o->WB("Zero ylow", hp.zero_ylow);
10437 o->WB("Log axis", hp.log_axis);
10438 o->WB("Show run markers", hp.show_run_markers);
10439 o->WB("Show values", hp.show_values);
10440 o->WB("Show fill", hp.show_fill);
10441 o->WB("Show factor and offset", hp.show_factor);
10442 //o->WB("Enable factor and offset", hp.enable_factor);
10443
10444 std::vector<std::string> hist_vars;
10445 std::vector<std::string> hist_formula;
10446 std::vector<std::string> hist_colour;
10447 std::vector<std::string> hist_label;
10448 std::vector<bool> hist_show_raw_value;
10449 std::vector<double> hist_factor;
10450 std::vector<double> hist_offset;
10451 std::vector<double> hist_voffset;
10452
10453 for (size_t i=0; i<hp.vars.size(); i++) {
10454 hist_vars.push_back(hp.vars[i].event_name + ":" + hp.vars[i].tag_name);
10455 hist_formula.push_back(hp.vars[i].formula);
10456 hist_colour.push_back(hp.vars[i].colour);
10457 hist_label.push_back(hp.vars[i].label);
10458 hist_show_raw_value.push_back(hp.vars[i].show_raw_value);
10459 hist_factor.push_back(hp.vars[i].factor);
10460 hist_offset.push_back(hp.vars[i].offset);
10461 hist_voffset.push_back(hp.vars[i].voffset);
10462 }
10463
10464 if (hp.vars.size() > 0) {
10465 o->WSA("Variables", hist_vars, 64);
10466 o->WSA("Formula", hist_formula, 64);
10467 o->WSA("Colour", hist_colour, NAME_LENGTH);
10468 o->WSA("Label", hist_label, NAME_LENGTH);
10469 o->WBA("Show raw value", hist_show_raw_value);
10470 o->WDA("Factor", hist_factor);
10471 o->WDA("Offset", hist_offset);
10472 o->WDA("VOffset", hist_voffset);
10473 } else {
10474 o->Delete("Variables");
10475 o->Delete("Formula");
10476 o->Delete("Colour");
10477 o->Delete("Label");
10478 o->Delete("Show raw value");
10479 o->Delete("Factor");
10480 o->Delete("Offset");
10481 o->Delete("VOffset");
10482 }
10483
10484 delete o;
10485}
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 1459 of file mhttpd.cxx.

1460{
1461 search_data* sinfo = (search_data*)info;
1462 int i;
1463 INT size, status;
1464
1465 Return* r = sinfo->r;
1466 const char* search_name = sinfo->search_name;
1467
1468 /* convert strings to uppercase */
1469
1470 char xstr1[MAX_ODB_PATH];
1471 for (i = 0; key->name[i]; i++)
1472 xstr1[i] = toupper(key->name[i]);
1473 xstr1[i] = 0;
1474
1475 char str2[MAX_ODB_PATH];
1476 for (i = 0; search_name[i] ; i++)
1477 str2[i] = toupper(search_name[i]);
1478 str2[i] = 0;
1479
1480 if (strstr(xstr1, str2) != NULL) {
1481 char data[10000];
1482 std::string path = db_get_path(hDB, hKey).substr(1);
1483 std::string path_encoded = urlEncode(path.c_str());
1484
1485 if (key->type == TID_KEY || key->type == TID_LINK) {
1486 /* for keys, don't display data value */
1487 r->rsprintf("<tr><td class=\"ODBkey\"><a href=\"?cmd=odb&odb_path=/%s\">/%s</a></tr>\n", path_encoded.c_str(), path.c_str());
1488 } else {
1489 /* strip variable name from path */
1490 char* p = const_cast<char *>(path.data() + path.length() - 1);
1491 while (*p && *p != '/')
1492 *p-- = 0;
1493 if (*p == '/')
1494 *p = 0;
1495
1496 /* display single value */
1497 if (key->num_values == 1) {
1498 size = sizeof(data);
1499 status = db_get_data(hDB, hKey, data, &size, key->type);
1500 std::string data_str;
1501 if (status == DB_NO_ACCESS)
1502 data_str = "<no read access>";
1503 else
1504 data_str = db_sprintf(data, key->item_size, 0, key->type);
1505
1506 r->rsprintf("<tr><td class=\"ODBkey\">");
1507 r->rsprintf("<a href=\"?cmd=odb&odb_path=/%s\">/%s/%s</a></td>", path_encoded.c_str(), path.c_str(), key->name);
1508 r->rsprintf("<td class=\"ODBvalue\">%s</td></tr>\n", data_str.c_str());
1509 } else {
1510 /* display first value */
1511 i = key->num_values;
1512 if (i > 10)
1513 i = 11;
1514 r->rsprintf("<tr><td rowspan=%d class=\"ODBkey\">", i);
1515 r->rsprintf("<a href=\"?cmd=odb&odb_path=/%s\">/%s/%s\n", path_encoded.c_str(), path.c_str(), key->name);
1516
1517 for (int i = 0; i < key->num_values; i++) {
1518 size = sizeof(data);
1519 db_get_data_index(hDB, hKey, data, &size, i, key->type);
1520
1521 std::string data_str = db_sprintf(data, key->item_size, 0, key->type);
1522
1523 if (i > 0)
1524 r->rsprintf("<tr>");
1525
1526 r->rsprintf("<td class=\"ODBvalue\">[%d] %s</td></tr>\n", i, data_str.c_str());
1527
1528 if (i > 8) {
1529 r->rsprintf("<tr><td class=\"ODBvalue\">... [%d] values ...</td></tr>\n", key->num_values - i - 1);
1530 break;
1531 }
1532 }
1533 }
1534 }
1535 }
1536
1537 return SUCCESS;
1538}
#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:1455
const char * search_name
Definition mhttpd.cxx:1456
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 7756 of file mhttpd.cxx.

7757{
7758 char mon[80];
7759 time_t t_sec;
7760
7761 t_sec = (time_t) sec;
7762
7763 struct tm tms;
7764 localtime_r(&t_sec, &tms);
7765 strcpy(mon, mname[tms.tm_mon]);
7766 mon[3] = 0;
7767
7768 if (force_date) {
7769 if (base < 600)
7770 sprintf(result, "%02d %s %02d %02d:%02d:%02d",
7771 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min,
7772 tms.tm_sec);
7773 else if (base < 3600 * 24)
7774 sprintf(result, "%02d %s %02d %02d:%02d",
7775 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7776 else
7777 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7778 } else {
7779 if (base < 600)
7780 sprintf(result, "%02d:%02d:%02d", tms.tm_hour, tms.tm_min, tms.tm_sec);
7781 else if (base < 3600 * 3)
7782 sprintf(result, "%02d:%02d", tms.tm_hour, tms.tm_min);
7783 else if (base < 3600 * 24)
7784 sprintf(result, "%02d %s %02d %02d:%02d",
7785 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7786 else
7787 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7788 }
7789}
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 1212 of file mhttpd.cxx.

1213{
1214 FILE *fp = fopen(path.c_str(), "rb");
1215
1216 if (!fp) {
1217 if (generate_404) {
1218 /* header */
1219 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1220 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1221 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1222 r->rsprintf("\r\n");
1223 r->rsprintf("Error: Cannot read \"%s\", fopen() errno %d (%s)\n", path.c_str(), errno, strerror(errno));
1224 }
1225 return false;
1226 }
1227
1228 return send_fp(r, path, fp);
1229}
bool send_fp(Return *r, const std::string &path, FILE *fp)
Definition mhttpd.cxx:1166
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 1166 of file mhttpd.cxx.

1167{
1168 assert(fp != NULL);
1169
1170 // send HTTP headers
1171
1172 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1173 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1174 r->rsprintf("Accept-Ranges: bytes\r\n");
1175
1176 // send HTTP cache control headers
1177
1178 time_t now = time(NULL);
1179 now += (int) (3600 * 24);
1180 struct tm gmt_tms;
1181 gmtime_r(&now, &gmt_tms);
1182 const char* format = "%A, %d-%b-%y %H:%M:%S GMT";
1183
1184 char str[256];
1185 strftime(str, sizeof(str), format, &gmt_tms);
1186 r->rsprintf("Expires: %s\r\n", str);
1187
1188 // send Content-Type header
1189
1190 r->rsprintf("Content-Type: %s\r\n", get_content_type(path.c_str()).c_str());
1191
1192 // send Content-Length header
1193
1194 struct stat stat_buf;
1195 fstat(fileno(fp), &stat_buf);
1196 int length = stat_buf.st_size;
1197 r->rsprintf("Content-Length: %d\r\n", length);
1198
1199 // send end of headers
1200
1201 r->rsprintf("\r\n");
1202
1203 // send file data
1204
1205 r->rread(path.c_str(), fileno(fp), length);
1206
1207 fclose(fp);
1208
1209 return true;
1210}
void rread(const char *filename, int fh, int len)
Definition mhttpd.cxx:588
std::string get_content_type(const char *filename)
Definition mhttpd.cxx:1135
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 12190 of file mhttpd.cxx.

12191{
12192 int length;
12193 const unsigned char *picon;
12194 char str[256], format[256];
12195 time_t now;
12196
12197 if (strstr(icon, "favicon.ico") != 0) {
12198 length = sizeof(favicon_ico);
12199 picon = favicon_ico;
12200 } else if (strstr(icon, "favicon.png") != 0) {
12201 length = sizeof(favicon_png);
12202 picon = favicon_png;
12203 } else
12204 return;
12205
12206 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
12207 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12208 r->rsprintf("Accept-Ranges: bytes\r\n");
12209
12210 /* set expiration time to one day */
12211 time(&now);
12212 now += (int) (3600 * 24);
12213 struct tm gmt_tms;
12214 gmtime_r(&now, &gmt_tms);
12215 strcpy(format, "%A, %d-%b-%y %H:%M:%S GMT");
12216 strftime(str, sizeof(str), format, &gmt_tms);
12217 r->rsprintf("Expires: %s\r\n", str);
12218
12219 if (equal_ustring(icon, "favicon.ico"))
12220 r->rsprintf("Content-Type: image/x-icon\r\n");
12221 else
12222 r->rsprintf("Content-Type: image/png\r\n");
12223
12224 r->rsprintf("Content-Length: %d\r\n\r\n", length);
12225
12226 r->rmemcpy(picon, length);
12227}
const unsigned char favicon_png[]
Definition mhttpd.cxx:217
const unsigned char favicon_ico[]
Definition mhttpd.cxx:282
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 1231 of file mhttpd.cxx.

1232{
1233 std::string path;
1234 FILE *fp = NULL;
1235
1236 bool found = open_resource_file(name.c_str(), &path, &fp);
1237
1238 if (!found) {
1239 if (generate_404) {
1240 /* header */
1241 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1242 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1243 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1244 r->rsprintf("\r\n");
1245 r->rsprintf("Error: resource file \"%s\" not found, see messages\n", name.c_str());
1246 }
1247 return false;
1248 }
1249
1250 return send_fp(r, path, fp);
1251}
bool open_resource_file(const char *filename, std::string *ppath, FILE **pfp)
Definition mhttpd.cxx:1031
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 1255 of file mhttpd.cxx.

1256{
1257 struct sockaddr_in bind_addr;
1258 struct hostent *phe;
1259 int i, s, strsize, offset;
1260 char *str, buf[256];
1261
1262 if (verbose)
1263 printf("\n\nEmail from %s to %s, SMTP host %s:\n", from, to, smtp_host);
1264
1265 /* create a new socket for connecting to remote server */
1266 s = socket(AF_INET, SOCK_STREAM, 0);
1267 if (s == -1)
1268 return -1;
1269
1270 /* connect to remote node port 25 */
1271 memset(&bind_addr, 0, sizeof(bind_addr));
1272 bind_addr.sin_family = AF_INET;
1273 bind_addr.sin_port = htons((short) 25);
1274
1275 phe = gethostbyname(smtp_host);
1276 if (phe == NULL)
1277 return -1;
1278 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
1279
1280 if (connect(s, (const sockaddr*)&bind_addr, sizeof(bind_addr)) < 0) {
1281 closesocket(s);
1282 return -1;
1283 }
1284
1285 strsize = TEXT_SIZE + 1000;
1286 str = (char*)malloc(strsize);
1287
1288 recv_string(s, str, strsize, 3000);
1289 if (verbose)
1290 puts(str);
1291
1292 /* drain server messages */
1293 do {
1294 str[0] = 0;
1295 recv_string(s, str, strsize, 300);
1296 if (verbose)
1297 puts(str);
1298 } while (str[0]);
1299
1300 sprintf(str, "HELO %s\r\n", from_host);
1301 send(s, str, strlen(str), 0);
1302 if (verbose)
1303 puts(str);
1304 recv_string(s, str, strsize, 3000);
1305 if (verbose)
1306 puts(str);
1307
1308 if (strchr(from, '<')) {
1309 mstrlcpy(buf, strchr(from, '<') + 1, sizeof(buf));
1310 if (strchr(buf, '>'))
1311 *strchr(buf, '>') = 0;
1312 } else
1313 mstrlcpy(buf, from, sizeof(buf));
1314
1315 sprintf(str, "MAIL FROM: %s\n", buf);
1316 send(s, str, strlen(str), 0);
1317 if (verbose)
1318 puts(str);
1319 recv_string(s, str, strsize, 3000);
1320 if (verbose)
1321 puts(str);
1322
1323 sprintf(str, "RCPT TO: <%s>\r\n", to);
1324 send(s, str, strlen(str), 0);
1325 if (verbose)
1326 puts(str);
1327 recv_string(s, str, strsize, 3000);
1328 if (verbose)
1329 puts(str);
1330
1331 sprintf(str, "DATA\r\n");
1332 send(s, str, strlen(str), 0);
1333 if (verbose)
1334 puts(str);
1335 recv_string(s, str, strsize, 3000);
1336 if (verbose)
1337 puts(str);
1338
1339 sprintf(str, "To: %s\r\nFrom: %s\r\nSubject: %s\r\n", to, from, subject);
1340 send(s, str, strlen(str), 0);
1341 if (verbose)
1342 puts(str);
1343
1344 sprintf(str, "X-Mailer: mhttpd revision %s\r\n", mhttpd_revision());
1345 send(s, str, strlen(str), 0);
1346 if (verbose)
1347 puts(str);
1348
1349 ss_tzset(); // required for localtime_r()
1350 time_t now;
1351 time(&now);
1352 struct tm tms;
1353 localtime_r(&now, &tms);
1354 strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S", &tms);
1355 offset = (-(int) timezone);
1356 if (tms.tm_isdst)
1357 offset += 3600;
1358 sprintf(str, "Date: %s %+03d%02d\r\n", buf, (int) (offset / 3600),
1359 (int) ((abs((int) offset) / 60) % 60));
1360 send(s, str, strlen(str), 0);
1361 if (verbose)
1362 puts(str);
1363
1364 sprintf(str, "Content-Type: TEXT/PLAIN; charset=US-ASCII\r\n\r\n");
1365 send(s, str, strlen(str), 0);
1366 if (verbose)
1367 puts(str);
1368
1369 /* analyze text for "." at beginning of line */
1370 const char* p = text;
1371 str[0] = 0;
1372 while (strstr(p, "\r\n.\r\n")) {
1373 i = (POINTER_T) strstr(p, "\r\n.\r\n") - (POINTER_T) p + 1;
1374 mstrlcat(str, p, i);
1375 p += i + 4;
1376 mstrlcat(str, "\r\n..\r\n", strsize);
1377 }
1378 mstrlcat(str, p, strsize);
1379 mstrlcat(str, "\r\n", strsize);
1380 send(s, str, strlen(str), 0);
1381 if (verbose)
1382 puts(str);
1383
1384 /* send ".<CR>" to signal end of message */
1385 sprintf(str, ".\r\n");
1386 send(s, str, strlen(str), 0);
1387 if (verbose)
1388 puts(str);
1389 recv_string(s, str, strsize, 3000);
1390 if (verbose)
1391 puts(str);
1392
1393 sprintf(str, "QUIT\n");
1394 send(s, str, strlen(str), 0);
1395 if (verbose)
1396 puts(str);
1397 recv_string(s, str, strsize, 3000);
1398 if (verbose)
1399 puts(str);
1400
1401 closesocket(s);
1402 free(str);
1403
1404 return 1;
1405}
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 16202 of file mhttpd.cxx.

16203{
16204 if (!params) {
16205 MJSO* doc = MJSO::I();
16206 doc->D("set new value of mhttpd http_trace");
16207 doc->P(NULL, MJSON_INT, "new value of http_trace");
16208 doc->R(NULL, MJSON_INT, "new value of http_trace");
16209 return doc;
16210 }
16211
16212 http_trace = params->GetInt();
16213 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16214}
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 5660 of file mhttpd.cxx.

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

3615{
3616 char str[256];
3617 std::string filename;
3618 HNDLE hDB;
3619
3621
3622 HNDLE hkey;
3623 sprintf(str, "/Custom/%s", name);
3624 db_find_key(hDB, 0, str, &hkey);
3625
3626 if (!hkey) {
3627 sprintf(str, "/Custom/%s&", name);
3628 db_find_key(hDB, 0, str, &hkey);
3629 if (!hkey) {
3630 sprintf(str, "/Custom/%s!", name);
3631 db_find_key(hDB, 0, str, &hkey);
3632 }
3633 }
3634
3635 if(!hkey){
3636 sprintf(str,"show_custom_file: Invalid custom page: \"/Custom/%s\" not found in ODB", name);
3637 show_error_404(r, str);
3638 return;
3639 }
3640
3641 int status;
3642 KEY key;
3643
3644 status = db_get_key(hDB, hkey, &key);
3645
3646 if (status != DB_SUCCESS) {
3647 char errtext[512];
3648 sprintf(errtext, "show_custom_file: Error: db_get_key() for \"%s\" status %d", str, status);
3649 show_error_404(r, errtext);
3650 return;
3651 }
3652
3653 int size = key.total_size;
3654 char* ctext = (char*)malloc(size);
3655
3656 status = db_get_data(hDB, hkey, ctext, &size, TID_STRING);
3657
3658 if (status != DB_SUCCESS) {
3659 char errtext[512];
3660 sprintf(errtext, "show_custom_file: Error: db_get_data() for \"%s\" status %d", str, status);
3661 show_error_404(r, errtext);
3662 free(ctext);
3663 return;
3664 }
3665
3666 filename = add_custom_path(ctext);
3667
3668 free(ctext);
3669
3670 send_file(r, filename, true);
3671
3672 return;
3673}
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 3677 of file mhttpd.cxx.

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

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

2487{
2488 HNDLE hDB;
2489 int size;
2490 int status;
2491 char file_name[256];
2492
2494 file_name[0] = 0;
2495 if (hDB > 0) {
2496 size = sizeof(file_name);
2497 memset(file_name, 0, size);
2498
2499 status = db_get_value(hDB, 0, "/Logger/Elog dir", file_name, &size, TID_STRING, FALSE);
2500 if (status != DB_SUCCESS)
2501 db_get_value(hDB, 0, "/Logger/Data dir", file_name, &size, TID_STRING, TRUE);
2502
2503 if (file_name[0] != 0)
2504 if (file_name[strlen(file_name) - 1] != DIR_SEPARATOR)
2505 mstrlcat(file_name, DIR_SEPARATOR_STR, sizeof(file_name));
2506 }
2507 mstrlcat(file_name, path, sizeof(file_name));
2508
2509 int fh = open(file_name, O_RDONLY | O_BINARY);
2510 if (fh > 0) {
2511 lseek(fh, 0, SEEK_END);
2512 int length = TELL(fh);
2513 lseek(fh, 0, SEEK_SET);
2514
2515 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
2516 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2517 r->rsprintf("Accept-Ranges: bytes\r\n");
2518 //r->rsprintf("Content-disposition: attachment; filename=%s\r\n", path);
2519
2520 r->rsprintf("Content-Type: %s\r\n", get_content_type(file_name).c_str());
2521
2522 r->rsprintf("Content-Length: %d\r\n\r\n", length);
2523
2524 r->rread(file_name, fh, length);
2525
2526 close(fh);
2527 }
2528
2529 return;
2530}
#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 2562 of file mhttpd.cxx.

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

1842{
1843 /* header */
1844 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1845 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1846 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1847
1848 r->rsprintf("<html><head>\n");
1849 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1850 r->rsprintf("<title>MIDAS error</title></head>\n");
1851 r->rsprintf("<body><H1>%s</H1></body></html>\n", error);
1852}
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 1856 of file mhttpd.cxx.

1857{
1858 /* header */
1859 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1860 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1861 r->rsprintf("Content-Type: text/plain\r\n");
1862 r->rsprintf("\r\n");
1863
1864 r->rsprintf("MIDAS error: %s\n", error);
1865}
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 7573 of file mhttpd.cxx.

7574{
7575 HNDLE hDB, hkey;
7576
7578
7579 if (value[0] == 0) {
7580 /* without value, show find dialog */
7581 show_header(r, "Find value", "GET", "", 0);
7582
7583 //end header:
7584 r->rsprintf("</table>");
7585
7586 //find dialog:
7587 r->rsprintf("<table class=\"dialogTable\">");
7588
7589 r->rsprintf("<tr><th colspan=2>Find string in Online Database</tr>\n");
7590 r->rsprintf("<tr><td>Enter substring (case insensitive)\n");
7591
7592 r->rsprintf("<td><input type=\"text\" size=\"20\" maxlength=\"80\" name=\"value\">\n");
7593 r->rsprintf("</tr>");
7594
7595 r->rsprintf("<tr><td align=center colspan=2>");
7596 r->rsprintf("<input type=submit name=cmd value=Find>");
7597 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7598 r->rsprintf("</tr>");
7599 r->rsprintf("</table>");
7600
7601 r->rsprintf("<input type=hidden name=cmd value=Find>");
7602
7603 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7604 r->rsprintf("</form>\n");
7605 r->rsprintf("</body></html>\r\n");
7606 } else {
7607 show_header(r, "Search results", "GET", "", 0);
7608
7609 r->rsprintf("<table class=\"mtable\">\n");
7610 r->rsprintf("<tr><th colspan=2 class=\"mtableheader\">");
7611 r->rsprintf("Results of search for substring \"%s\"</tr>\n", value);
7612 r->rsprintf("<tr><th class=\"titlerow\">Key<th>Value</tr>\n");
7613
7614 /* start from root */
7615 db_find_key(hDB, 0, "", &hkey);
7616 assert(hkey);
7617
7618 /* scan tree, call "search_callback" for each key */
7620 data.r = r;
7621 data.search_name = value;
7622
7623 db_scan_tree(hDB, hkey, 0, search_callback, (void *)&data);
7624
7625 r->rsprintf("</table>");
7626 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7627 r->rsprintf("</form>\n");
7628 r->rsprintf("</body></html>\r\n");
7629 }
7630}
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:1459
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 1781 of file mhttpd.cxx.

1782{
1783 HNDLE hDB;
1784 time_t now;
1785 char str[256];
1786
1788
1789 /* header */
1790 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1791 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1792 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1793 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1794 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1795
1796 r->rsprintf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
1797 r->rsprintf("<html><head>\n");
1798
1799 /* style sheet */
1800 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
1801 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1802 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
1803
1804 /* auto refresh */
1805 if (refresh > 0)
1806 r->rsprintf("<meta http-equiv=\"Refresh\" content=\"%02d\">\n", refresh);
1807
1808 r->rsprintf("<title>%s</title></head>\n", title);
1809
1810 mstrlcpy(str, path, sizeof(str));
1811 urlEncode(str, sizeof(str));
1812
1813 if (equal_ustring(method, "POST"))
1814 r->rsprintf
1815 ("<body><form name=\"form1\" method=\"POST\" action=\"%s\" enctype=\"multipart/form-data\">\n\n",
1816 str);
1817 else if (equal_ustring(method, "GET"))
1818 r->rsprintf("<body><form name=\"form1\" method=\"GET\" action=\"%s\">\n\n", str);
1819
1820 /* title row */
1821
1822 std::string exptname;
1823 db_get_value_string(hDB, 0, "/Experiment/Name", 0, &exptname, TRUE);
1824 time(&now);
1825}
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 1542 of file mhttpd.cxx.

1543{
1544 const char *s;
1545 char str[256];
1546 int status;
1547
1548 show_header(r, "Help", "", "./", 0);
1549 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
1550 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
1551 show_navigation_bar(r, "Help");
1552
1553 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1554 r->rsprintf(" <tr>\n");
1555 r->rsprintf(" <td class=\"mtableheader\">MIDAS Help Page</td>\n");
1556 r->rsprintf(" </tr>\n");
1557 r->rsprintf(" <tr>\n");
1558 r->rsprintf(" <td>\n");
1559 r->rsprintf(" <table>\n");
1560
1561 r->rsprintf(" <tr>\n");
1562 r->rsprintf(" <td style=\"text-align:right;\">Documentation:</td>\n");
1563 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://midas.triumf.ca\">https://midas.triumf.ca</a></td>\n");
1564 r->rsprintf(" </tr>\n");
1565 r->rsprintf(" <tr>\n");
1566 r->rsprintf(" <td style=\"text-align:right;\">Discussion Forum:</td>\n");
1567 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://midas.triumf.ca/forum/\">https://midas.triumf.ca/forum/</a></td>\n");
1568 r->rsprintf(" </tr>\n");
1569 r->rsprintf(" <tr>\n");
1570 r->rsprintf(" <td style=\"text-align:right;\">Code:</td>\n");
1571 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://bitbucket.org/tmidas/midas/\">https://bitbucket.org/tmidas/midas/</a></td>\n");
1572 r->rsprintf(" </tr>\n");
1573 r->rsprintf(" <tr>\n");
1574 r->rsprintf(" <td style=\"text-align:right;\">Report a bug:</td>\n");
1575 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://bitbucket.org/tmidas/midas/issues/\">https://bitbucket.org/tmidas/midas/issues/</a></td>\n");
1576 r->rsprintf(" </tr>\n");
1577
1578 r->rsprintf(" <tr>\n");
1579 r->rsprintf(" <td style=\"text-align:right;\">Version:</td>\n");
1580 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_version());
1581 r->rsprintf(" </tr>\n");
1582 r->rsprintf(" <tr>\n");
1583 r->rsprintf(" <td style=\"text-align:right;\">Revision:</td>\n");
1584 std::string rev = cm_get_revision();
1585 std::string url = "https://bitbucket.org/tmidas/midas/commits/";
1586 // rev format looks like this:
1587 // Fri Nov 24 10:15:54 2017 -0800 - midas-2017-07-c-171-gb8928d5c-dirty on branch develop
1588 // -gXXX is the commit hash
1589 // -dirty should be removed from the hash url, if present
1590 // " " before "on branch" should be removed from the hash url
1591 std::string::size_type pos = rev.find("-g");
1592 if (pos != std::string::npos) {
1593 std::string hash = rev.substr(pos+2);
1594 pos = hash.find("-dirty");
1595 if (pos != std::string::npos) {
1596 hash = hash.substr(0, pos);
1597 }
1598 pos = hash.find(" ");
1599 if (pos != std::string::npos) {
1600 hash = hash.substr(0, pos);
1601 }
1602 url += hash;
1603 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"%s\">%s</a></td>\n", url.c_str(), rev.c_str());
1604 } else {
1605 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", rev.c_str());
1606 }
1607 r->rsprintf(" </tr>\n");
1608
1609 r->rsprintf(" <tr>\n");
1610 r->rsprintf(" <td style=\"text-align:right;\">MIDASSYS:</td>\n");
1611 s = getenv("MIDASSYS");
1612 if (!s) s = "(unset)";
1613 mstrlcpy(str, s, sizeof(str));
1614 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", str);
1615 r->rsprintf(" </tr>\n");
1616
1617 r->rsprintf(" <tr>\n");
1618 r->rsprintf(" <td style=\"text-align:right;\">mhttpd current directory:</td>\n");
1619 std::string cwd = ss_getcwd();
1620 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cwd.c_str());
1621 r->rsprintf(" </tr>\n");
1622
1623 r->rsprintf(" <tr>\n");
1624 r->rsprintf(" <td style=\"text-align:right;\">Exptab file:</td>\n");
1625 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_exptab_filename().c_str());
1626 r->rsprintf(" </tr>\n");
1627
1628 r->rsprintf(" <tr>\n");
1629 r->rsprintf(" <td style=\"text-align:right;\">Experiment:</td>\n");
1630 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_experiment_name().c_str());
1631 r->rsprintf(" </tr>\n");
1632
1633 r->rsprintf(" <tr>\n");
1634 r->rsprintf(" <td style=\"text-align:right;\">Experiment directory:</td>\n");
1635 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_path().c_str());
1636 r->rsprintf(" </tr>\n");
1637
1640
1641 if (status == CM_SUCCESS) {
1642 if (list.size() == 1) {
1643 r->rsprintf(" <tr>\n");
1644 r->rsprintf(" <td style=\"text-align:right;\">System logfile:</td>\n");
1645 std::string s;
1646 cm_msg_get_logfile("midas", 0, &s, NULL, NULL);
1647 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", s.c_str());
1648 r->rsprintf(" </tr>\n");
1649 } else {
1650 r->rsprintf(" <tr>\n");
1651 r->rsprintf(" <td style=\"text-align:right;\">Logfiles:</td>\n");
1652 r->rsprintf(" <td style=\"text-align:left;\">\n");
1653 for (unsigned i=0 ; i<list.size() ; i++) {
1654 if (i>0)
1655 r->rsputs("<br />\n");
1656 std::string s;
1657 cm_msg_get_logfile(list[i].c_str(), 0, &s, NULL, NULL);
1658 r->rsputs(s.c_str());
1659 }
1660 r->rsprintf("\n </td>\n");
1661 r->rsprintf(" </tr>\n");
1662 }
1663 }
1664
1665 r->rsprintf(" <tr>\n");
1666 r->rsprintf(" <td style=\"text-align:right;\">Image history:</td>\n");
1667 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_history_path("IMAGE").c_str());
1668 r->rsprintf(" </tr>\n");
1669
1670 r->rsprintf(" <tr>\n");
1671 r->rsprintf(" <td style=\"text-align:right;\">Resource paths:</td>\n");
1672 r->rsprintf(" <td style=\"text-align:left;\">");
1673 std::vector<std::string> resource_paths = get_resource_paths();
1674 for (unsigned i=0; i<resource_paths.size(); i++) {
1675 if (i>0)
1676 r->rsputs("<br>");
1677 r->rsputs(resource_paths[i].c_str());
1678 std::string exp = cm_expand_env(resource_paths[i].c_str());
1679 //printf("%d %d [%s] [%s]\n", resource_paths[i].length(), exp.length(), resource_paths[i].c_str(), exp.c_str());
1680 if (exp != resource_paths[i]) {
1681 r->rsputs(" (");
1682 r->rsputs(exp.c_str());
1683 r->rsputs(")");
1684 }
1685 }
1686 r->rsprintf(" </td>\n");
1687 r->rsprintf(" </tr>\n");
1688
1689 std::string path;
1690
1691 r->rsprintf(" <tr>\n");
1692 r->rsprintf(" <td style=\"text-align:right;\">midas.css:</td>\n");
1693 if (open_resource_file("midas.css", &path, NULL))
1694 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1695 else
1696 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1697 r->rsprintf(" </tr>\n");
1698
1699 r->rsprintf(" <tr>\n");
1700 r->rsprintf(" <td style=\"text-align:right;\">midas.js:</td>\n");
1701 if (open_resource_file("midas.js", &path, NULL))
1702 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1703 else
1704 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1705 r->rsprintf(" </tr>\n");
1706
1707 r->rsprintf(" <tr>\n");
1708 r->rsprintf(" <td style=\"text-align:right;\">controls.js:</td>\n");
1709 if (open_resource_file("controls.js", &path, NULL))
1710 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1711 else
1712 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1713 r->rsprintf(" </tr>\n");
1714
1715 r->rsprintf(" <tr>\n");
1716 r->rsprintf(" <td style=\"text-align:right;\">mhttpd.js:</td>\n");
1717 if (open_resource_file("mhttpd.js", &path, NULL))
1718 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1719 else
1720 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1721 r->rsprintf(" </tr>\n");
1722
1723 r->rsprintf(" <tr>\n");
1724 r->rsprintf(" <td style=\"text-align:right;\">obsolete.js:</td>\n");
1725 if (open_resource_file("obsolete.js", &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;\">Obsolete mhttpd.css:</td>\n");
1733 if (open_resource_file("mhttpd.css", &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;\">JSON-RPC schema:</td>\n");
1741 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");
1742 r->rsprintf(" </tr>\n");
1743
1744 r->rsprintf(" <tr>\n");
1745 r->rsprintf(" <td style=\"text-align:right;\">JavaScript examples:</td>\n");
1746 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=example\">example.html</a></td>\n");
1747 r->rsprintf(" </tr>\n");
1748
1749 r->rsprintf(" <tr>\n");
1750 r->rsprintf(" <td style=\"text-align:right;\">Custom page example:</td>\n");
1751 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=custom_example\">custom_example.html</a></td>\n");
1752 r->rsprintf(" </tr>\n");
1753
1754 r->rsprintf(" <tr>\n");
1755 r->rsprintf(" <td style=\"text-align:right;\">MPlot custom plot examples:</td>\n");
1756 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=plot_example\">plot_example.html</a></td>\n");
1757 r->rsprintf(" </tr>\n");
1758
1759 r->rsprintf(" </table>\n");
1760 r->rsprintf(" </td>\n");
1761 r->rsprintf(" </tr>\n");
1762 r->rsprintf("</table>\n");
1763
1764 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1765 r->rsprintf(" <tr>\n");
1766 r->rsprintf(" <td class=\"mtableheader\">Contributions</td>\n");
1767 r->rsprintf(" </tr>\n");
1768 r->rsprintf(" <tr>\n");
1769 r->rsprintf(" <td>\n");
1770 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");
1771 r->rsprintf(" </td>\n");
1772 r->rsprintf(" </tr>\n");
1773 r->rsprintf("</table>\n");
1774
1775 r->rsprintf("</div></form>\n");
1776 r->rsprintf("</body></html>\r\n");
1777}
std::string cm_get_exptab_filename()
Definition midas.cxx:1803
const char * cm_get_version()
Definition midas.cxx:1491
std::string cm_get_experiment_name()
Definition midas.cxx:1595
INT EXPRT cm_msg_facilities(STRING_LIST *list)
Definition midas.cxx:517
void cm_msg_get_logfile(const char *fac, time_t t, std::string *filename, std::string *linkname, std::string *linktarget)
Definition midas.cxx:552
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 10525 of file mhttpd.cxx.

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

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

1870{
1871 r->rsprintf("<script>\n");
1872 r->rsprintf("window.addEventListener(\"load\", function(e) { mhttpd_init('%s', 1000); });\n", cur_page);
1873 r->rsprintf("</script>\n");
1874
1875 r->rsprintf("<!-- header and side navigation will be filled in mhttpd_init -->\n");
1876 r->rsprintf("<div id=\"mheader\"></div>\n");
1877 r->rsprintf("<div id=\"msidenav\"></div>\n");
1878 r->rsprintf("<div id=\"mmain\">\n");
1879}
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 6799 of file mhttpd.cxx.

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

3281{
3282 int size, index, i_edit, i_set;
3283 char data[TEXT_SIZE], full_keypath[256], keypath[256], *p;
3284 HNDLE hDB, hkey;
3285 KEY key;
3286
3287 /* check if variable to edit */
3288 i_edit = -1;
3289 if (equal_ustring(pp->getparam("cmd"), "Edit"))
3290 i_edit = atoi(pp->getparam("index"));
3291
3292 /* check if variable to set */
3293 i_set = -1;
3294 if (equal_ustring(pp->getparam("cmd"), "Set"))
3295 i_set = atoi(pp->getparam("index"));
3296
3297 /* check if path contains index */
3298 mstrlcpy(full_keypath, keypath1, sizeof(full_keypath));
3299 mstrlcpy(keypath, keypath1, sizeof(keypath));
3300 index = 0;
3301
3302 if (strchr(keypath, '[') && strchr(keypath, ']')) {
3303 for (p = strchr(keypath, '[') + 1; *p && *p != ']'; p++)
3304 if (!isdigit(*p))
3305 break;
3306
3307 if (*p && *p == ']') {
3308 index = atoi(strchr(keypath, '[') + 1);
3309 *strchr(keypath, '[') = 0;
3310 }
3311 }
3312
3314 db_find_key(hDB, 0, keypath, &hkey);
3315 if (!hkey)
3316 r->rsprintf("<b>Key \"%s\" not found in ODB</b>\n", keypath);
3317 else {
3318 db_get_key(hDB, hkey, &key);
3319 size = sizeof(data);
3320 db_get_data_index(hDB, hkey, data, &size, index, key.type);
3321
3322 std::string data_str;
3323 if (format && strlen(format)>0)
3324 data_str = db_sprintff(format, data, key.item_size, 0, key.type);
3325 else
3326 data_str= db_sprintf(data, key.item_size, 0, key.type);
3327
3328 if (equal_ustring(type, "checkbox")) {
3329
3330 if (pp->isparam("cbi"))
3331 i_set = atoi(pp->getparam("cbi"));
3332 if (n_var == i_set) {
3333 /* toggle state */
3334 if (key.type == TID_BOOL) {
3335 if (data_str[0] == 'y')
3336 data_str = "n";
3337 else
3338 data_str = "y";
3339 } else {
3340 if (atoi(data_str.c_str()) > 0)
3341 data_str = "0";
3342 else
3343 data_str = "1";
3344 }
3345
3346 db_sscanf(data_str.c_str(), data, &size, 0, key.type);
3347 db_set_data_index(hDB, hkey, data, size, index, key.type);
3348 }
3349
3350 std::string options;
3351 if (data_str[0] == 'y' || atoi(data_str.c_str()) > 0)
3352 options += "checked ";
3353 if (!edit)
3354 options += "disabled ";
3355 else {
3356 if (edit == 1) {
3357 options += "onClick=\"o=document.createElement('input');o.type='hidden';o.name='cbi';o.value='";
3358 options += msprintf("%d", n_var);
3359 options += "';document.form1.appendChild(o);";
3360 options += "document.form1.submit();\" ";
3361 }
3362 }
3363
3364 if (tail[0])
3365 options += tail;
3366
3367 r->rsprintf("<input type=\"checkbox\" %s>\n", options.c_str());
3368
3369 } else { // checkbox
3370
3371 if (edit == 1) {
3372 if (n_var == i_set) {
3373 /* set value */
3374 char str[256];
3375 mstrlcpy(str, pp->getparam("value"), sizeof(str));
3376 db_sscanf(str, data, &size, 0, key.type);
3377 db_set_data_index(hDB, hkey, data, size, index, key.type);
3378
3379 /* read back value */
3380 size = sizeof(data);
3381 db_get_data_index(hDB, hkey, data, &size, index, key.type);
3382 data_str = db_sprintf(data, key.item_size, 0, key.type);
3383 }
3384
3385 if (n_var == i_edit) {
3386 r->rsprintf("<input type=text size=10 maxlength=80 name=value value=\"%s\">\n", data_str.c_str());
3387 r->rsprintf("<input type=submit size=20 name=cmd value=Set>\n");
3388 r->rsprintf("<input type=hidden name=index value=%d>\n", n_var);
3389 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
3390 } else {
3391 if (edit == 2) {
3392 /* edit handling through user supplied JavaScript */
3393 r->rsprintf("<a href=\"#\" %s>", tail);
3394 } else {
3395 /* edit handling through form submission */
3396 if (pwd[0]) {
3397 r->rsprintf("<a onClick=\"promptpwd('%s?cmd=Edit&index=%d&pnam=%s')\" href=\"#\">", path, n_var, pwd);
3398 } else {
3399 r->rsprintf("<a href=\"%s?cmd=Edit&index=%d\" %s>", path, n_var, tail);
3400 }
3401 }
3402
3403 r->rsputs(data_str.c_str());
3404 r->rsprintf("</a>");
3405 }
3406 } else if (edit == 2) {
3407 r->rsprintf("<a href=\"#\" onclick=\"ODBEdit('%s')\">\n", full_keypath);
3408 r->rsputs(data_str.c_str());
3409 r->rsprintf("</a>");
3410 }
3411 else
3412 r->rsputs(data_str.c_str());
3413 }
3414 }
3415}
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 6708 of file mhttpd.cxx.

6709{
6710 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6711 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6712 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6713
6714 r->rsprintf("<html><head>\n");
6715 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6716 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6717 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6718 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6719
6720 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6721
6722 /*---- page header ----*/
6723 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6724
6725 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6726 if (password[0])
6727 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6728
6729 r->rsprintf("<tr><th>Please enter password</tr>\n");
6730 r->rsprintf("<tr><td align=center><input type=password name=pwd></tr>\n");
6731 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6732
6733 r->rsprintf("</table>\n");
6734
6735 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6736 r->rsprintf("</form>\n");
6737 r->rsprintf("</body></html>\r\n");
6738}
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 9797 of file mhttpd.cxx.

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

7442{
7443 int status, size;
7444 HNDLE hDB, hkey;
7445 KEY key;
7446 char data[TEXT_SIZE];
7447
7448 std::string odb_path = pp->getparam("odb_path");
7449
7450 //printf("show_set_page: odb_path [%s] group [%s] index %d value [%s]\n", odb_path.c_str(), group, index, value);
7451
7453
7454 /* show set page if no value is given */
7455 if (!pp->isparam("value") && !*pp->getparam("text")) {
7456 status = db_find_link(hDB, 0, odb_path.c_str(), &hkey);
7457 if (status != DB_SUCCESS) {
7458 r->rsprintf("Error: cannot find key %s<P>\n", odb_path.c_str());
7459 return;
7460 }
7461 db_get_link(hDB, hkey, &key);
7462
7463 show_header(r, "Set value", "POST", "", 0);
7464 //close header:
7465 r->rsprintf("</table>");
7466
7467 //main table:
7468 r->rsprintf("<table class=\"dialogTable\">");
7469
7470 if (index > 0)
7471 r->rsprintf("<input type=hidden name=index value=\"%d\">\n", index);
7472 else
7473 index = 0;
7474
7475 if (group[0])
7476 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", group);
7477
7478 r->rsprintf("<input type=hidden name=odb_path value=\"%s\">\n", odb_path.c_str());
7479
7480 std::string data_str1 = rpc_tid_name(key.type);
7481 std::string str1;
7482 if (key.num_values > 1) {
7483 data_str1 += msprintf("[%d]", key.num_values);
7484 str1 = msprintf("%s[%d]", odb_path.c_str(), index);
7485 } else
7486 str1 = odb_path.c_str();
7487
7488 r->rsprintf("<tr><th colspan=2>Set new value - type = %s</tr>\n", data_str1.c_str());
7489 r->rsprintf("<tr><td>%s<td>\n", str1.c_str());
7490
7491 /* set current value as default */
7492 size = sizeof(data);
7493 db_get_link_data(hDB, hkey, data, &size, key.type);
7494 std::string data_str = db_sprintf(data, key.item_size, index, key.type);
7495
7496 if (equal_ustring(data_str.c_str(), "<NULL>"))
7497 data_str = "";
7498
7499 if (strchr(data_str.c_str(), '\n') != NULL) {
7500 r->rsprintf("<textarea rows=20 cols=80 name=\"text\">\n");
7501 strencode3(r, data);
7502 r->rsprintf("</textarea>\n");
7503 } else {
7504 size = 20;
7505 if ((int) data_str.length() > size)
7506 size = data_str.length() + 3;
7507 if (size > 80)
7508 size = 80;
7509
7510 r->rsprintf("<input type=\"text\" size=%d maxlength=256 name=\"value\" value=\"", size);
7511 strencode(r, data_str.c_str());
7512 r->rsprintf("\">\n");
7513 }
7514
7515 r->rsprintf("</tr>\n");
7516
7517 r->rsprintf("<tr><td align=center colspan=2>");
7518 r->rsprintf("<input type=submit name=cmd value=Set>");
7519 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7520 r->rsprintf("</tr>");
7521 r->rsprintf("</table>");
7522
7523 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
7524
7525 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7526 r->rsprintf("</form>\n");
7527 r->rsprintf("</body></html>\r\n");
7528 return;
7529 } else {
7530 /* set value */
7531
7532 status = db_find_link(hDB, 0, odb_path.c_str(), &hkey);
7533 if (status != DB_SUCCESS) {
7534 r->rsprintf("Error: cannot find key %s<P>\n", odb_path.c_str());
7535 return;
7536 }
7537 db_get_link(hDB, hkey, &key);
7538
7539 memset(data, 0, sizeof(data));
7540
7541 if (pp->getparam("text") && *pp->getparam("text"))
7542 mstrlcpy(data, pp->getparam("text"), sizeof(data));
7543 else
7544 db_sscanf(value, data, &size, 0, key.type);
7545
7546 if (index < 0)
7547 index = 0;
7548
7549 /* extend data size for single string if necessary */
7550 if ((key.type == TID_STRING || key.type == TID_LINK)
7551 && (int) strlen(data) + 1 > key.item_size && key.num_values == 1)
7552 key.item_size = strlen(data) + 1;
7553
7554 if (key.item_size == 0)
7556
7557 if (key.num_values > 1)
7559 else
7561
7562 if (status == DB_NO_ACCESS)
7563 r->rsprintf("<h2>Write access not allowed</h2>\n");
7564
7565 redirect(r, "");
7566
7567 return;
7568 }
7569}
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7196
INT db_set_link_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7520
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 1829 of file mhttpd.cxx.

1830{
1831 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1832 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1833 r->rsprintf("Access-Control-Allow-Origin: *\r\n");
1834 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1835 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1836 r->rsprintf("Content-Type: text/plain; charset=%s\r\n\r\n", HTTP_ENCODING);
1837}
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 10504 of file mhttpd.cxx.

10505{
10506 /* sort variables according to "hist_order" */
10507
10508 bool need_sort = false;
10509 for (size_t i=1; i<hp.vars.size(); i++) {
10510 if (hp.vars[i-1].order >= hp.vars[i].order) {
10511 need_sort = true;
10512 }
10513 }
10514
10515 if (need_sort) {
10516 /* sort variables by order */
10517 std::sort(hp.vars.begin(), hp.vars.end(), cmp_vars);
10518
10519 /* renumber the variables according to the new sorted order */
10520 for (size_t index=0; index<hp.vars.size(); index++)
10521 hp.vars[index].order = (index+1)*10;
10522 }
10523}
static bool cmp_vars(const HistVar &a, const HistVar &b)
Definition mhttpd.cxx:10107
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 10157 of file mhttpd.cxx.

10157 {
10158 event_name = "";
10159 tag_name = "";
10160
10161 std::vector<size_t> colons;
10162
10163 for (size_t i = 0; i < var_name.size(); i++) {
10164 if (var_name[i] == ':') {
10165 colons.push_back(i);
10166 }
10167 }
10168
10169 if (colons.size() == 0) {
10170 // No colons - leave the tag name empty
10171 event_name = var_name;
10172 } else {
10173 size_t split_pos;
10174 size_t slash_pos = var_name.find("/");
10175 bool uses_per_variable_naming = (slash_pos != std::string::npos);
10176
10177 if (uses_per_variable_naming && colons.size() % 2 == 1) {
10178 size_t middle_colon_pos = colons[colons.size() / 2];
10179 std::string slash_to_mid = var_name.substr(slash_pos + 1, middle_colon_pos - slash_pos - 1);
10180 std::string mid_to_end = var_name.substr(middle_colon_pos + 1);
10181
10182 if (slash_to_mid == mid_to_end) {
10183 // Special case - we have a string of the form Beamlime/GS2:FC1:GS2:FC1.
10184 // Logger has already warned people that having colons in the equipment/event
10185 // names is a bad idea, so we only need to worry about them in the tag name.
10186 split_pos = middle_colon_pos;
10187 } else {
10188 // We have a string of the form Beamlime/Demand:GS2:FC1. Split at the first colon.
10189 split_pos = colons[0];
10190 }
10191 } else {
10192 // Normal case - split at the fist colon.
10193 split_pos = colons[0];
10194 }
10195
10196 event_name = var_name.substr(0, split_pos);
10197 tag_name = var_name.substr(split_pos + 1);
10198 }
10199}
Here is the caller graph for this function:

◆ starts_with()

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

Definition at line 4438 of file mhttpd.cxx.

4439{
4440 if (s1.length() < strlen(s2))
4441 return false;
4442 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4443}
Here is the caller graph for this function:

◆ strencode()

void strencode ( Return r,
const char *  text 
)

Definition at line 2022 of file mhttpd.cxx.

2023{
2024 size_t len = strlen(text);
2025 for (size_t i = 0; i < len; i++) {
2026 switch (text[i]) {
2027 case '\n':
2028 r->rsprintf("<br>\n");
2029 break;
2030 case '<':
2031 r->rsprintf("&lt;");
2032 break;
2033 case '>':
2034 r->rsprintf("&gt;");
2035 break;
2036 case '&':
2037 r->rsprintf("&amp;");
2038 break;
2039 case '\"':
2040 r->rsprintf("&quot;");
2041 break;
2042 default:
2043 r->rsprintf("%c", text[i]);
2044 }
2045 }
2046}
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 2050 of file mhttpd.cxx.

2051{
2052 std::string b;
2053 size_t len = strlen(text);
2054 for (size_t i = 0; i < len; i++) {
2055 switch (text[i]) {
2056 case '\n':
2057 b += "<br>\n";
2058 break;
2059 case '<':
2060 b += "&lt;";
2061 break;
2062 case '>':
2063 b += "&gt;";
2064 break;
2065 case '&':
2066 b += "&amp;";
2067 break;
2068 case '\"':
2069 b += "&quot;";
2070 break;
2071 default:
2072 b += text[i];
2073 break;
2074 }
2075 }
2076 return b;
2077}
Here is the caller graph for this function:

◆ strencode3()

void strencode3 ( Return r,
const char *  text 
)

Definition at line 2081 of file mhttpd.cxx.

2082{
2083 size_t len = strlen(text);
2084 for (size_t i = 0; i < len; i++) {
2085 switch (text[i]) {
2086 case '<':
2087 r->rsprintf("&lt;");
2088 break;
2089 case '>':
2090 r->rsprintf("&gt;");
2091 break;
2092 case '&':
2093 r->rsprintf("&amp;");
2094 break;
2095 case '\"':
2096 r->rsprintf("&quot;");
2097 break;
2098 default:
2099 r->rsprintf("%c", text[i]);
2100 }
2101 }
2102}
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 2106 of file mhttpd.cxx.

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

◆ string_to_time()

time_t string_to_time ( const char *  str)

Definition at line 8123 of file mhttpd.cxx.

8124{
8125 time_t t = 0;
8126 for (; *str != 0; str++) {
8127 if (*str < '0')
8128 break;
8129 if (*str > '9')
8130 break;
8131 t *= 10;
8132 t += *str - '0';
8133 }
8134 return t;
8135}
Here is the caller graph for this function:

◆ stristr()

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

Definition at line 341 of file mhttpd.cxx.

342{
343 char c1, c2, *ps, *pp;
344
345 if (str == NULL || pattern == NULL)
346 return NULL;
347
348 while (*str) {
349 ps = (char *) str;
350 pp = (char *) pattern;
351 c1 = *ps;
352 c2 = *pp;
353 if (toupper(c1) == toupper(c2)) {
354 while (*pp) {
355 c1 = *ps;
356 c2 = *pp;
357
358 if (toupper(c1) != toupper(c2))
359 break;
360
361 ps++;
362 pp++;
363 }
364
365 if (!*pp)
366 return (char *) str;
367 }
368 str++;
369 }
370
371 return NULL;
372}

◆ submit_elog()

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

Definition at line 2251 of file mhttpd.cxx.

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

7794{
7795 int dx, x_act, label_dx, major_dx, x_screen, maxwidth;
7796 int tick_base, major_base, label_base, xs, xl;
7797 char str[80];
7798 const int base[] = { 1, 5, 10, 60, 300, 600, 1800, 3600, 3600 * 6, 3600 * 12, 3600 * 24, 0 };
7799 time_t ltime;
7800 int force_date, d1, d2;
7801 struct tm tms;
7802
7803 if (xmax <= xmin || width <= 0)
7804 return;
7805
7806 /* force date display if xmax not today */
7807 ltime = ss_time();
7808 localtime_r(&ltime, &tms);
7809 d1 = tms.tm_mday;
7810 ltime = (time_t) xmax;
7811 localtime_r(&ltime, &tms);
7812 d2 = tms.tm_mday;
7813 force_date = (d1 != d2);
7814
7815 /* use 5 pixel as min tick distance */
7816 dx = (int) ((xmax - xmin) / (double) (width / 5) + 0.5);
7817
7818 for (tick_base = 0; base[tick_base]; tick_base++) {
7819 if (base[tick_base] > dx)
7820 break;
7821 }
7822 if (!base[tick_base])
7823 tick_base--;
7824 dx = base[tick_base];
7825
7826 if (base[tick_base + 1])
7827 major_base = tick_base + 1;
7828 else
7829 major_base = tick_base;
7830 major_dx = base[major_base];
7831
7832 if (base[major_base + 1])
7833 label_base = major_base + 1;
7834 else
7835 label_base = major_base;
7836 label_dx = base[label_base];
7837
7838 do {
7839 sec_to_label(str, (int) (xmin + 0.5), label_dx, force_date);
7840 maxwidth = font->h / 2 * strlen(str);
7841
7842 /* increasing label_dx, if labels would overlap */
7843 if (maxwidth > 0.7 * label_dx / (xmax - xmin) * width) {
7844 if (base[label_base + 1])
7845 label_dx = base[++label_base];
7846 else
7847 label_dx += 3600 * 24;
7848 } else
7849 break;
7850 } while (1);
7851
7852 x_act =
7853 (int) floor((double) (xmin - ss_timezone()) / label_dx) * label_dx + ss_timezone();
7854
7855 gdImageLine(im, x1, y1, x1 + width, y1, col);
7856
7857 do {
7858 x_screen = (int) ((x_act - xmin) / (xmax - xmin) * width + x1 + 0.5);
7859 xs = (int) (x_screen + 0.5);
7860
7861 if (x_screen > x1 + width + 0.001)
7862 break;
7863
7864 if (x_screen >= x1) {
7865 if ((x_act - ss_timezone()) % major_dx == 0) {
7866 if ((x_act - ss_timezone()) % label_dx == 0) {
7867 /* label tick mark */
7868 gdImageLine(im, xs, y1, xs, y1 + text, col);
7869
7870 /* grid line */
7871 if (grid != 0 && xs > x1 && xs < x1 + width)
7872 gdImageLine(im, xs, y1, xs, y1 + grid, col);
7873
7874 /* label */
7875 if (label != 0) {
7876 sec_to_label(str, x_act, label_dx, force_date);
7877
7878 /* if labels at edge, shift them in */
7879 xl = (int) xs - font->w * strlen(str) / 2;
7880 if (xl < 0)
7881 xl = 0;
7882 if (xl + font->w * (int) strlen(str) > xr)
7883 xl = xr - font->w * strlen(str);
7884 gdImageString(im, font, xl, y1 + label, str, col);
7885 }
7886 } else {
7887 /* major tick mark */
7888 gdImageLine(im, xs, y1, xs, y1 + major, col);
7889
7890 /* grid line */
7891 if (grid != 0 && xs > x1 && xs < x1 + width)
7892 gdImageLine(im, xs, y1 - 1, xs, y1 + grid, gcol);
7893 }
7894
7895 } else
7896 /* minor tick mark */
7897 gdImageLine(im, xs, y1, xs, y1 + minor, col);
7898
7899 }
7900
7901 x_act += dx;
7902
7903 /* supress 1.23E-17 ... */
7904 if (fabs((double)x_act) < dx / 100)
7905 x_act = 0;
7906
7907 } while (1);
7908}
INT ss_timezone()
Definition system.cxx:3652
void sec_to_label(char *result, int sec, int base, int force_date)
Definition mhttpd.cxx:7756
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 8098 of file mhttpd.cxx.

8099{
8100 double s;
8101
8102 s = atof(str);
8103 switch (str[strlen(str) - 1]) {
8104 case 'm':
8105 case 'M':
8106 s *= 60;
8107 break;
8108 case 'h':
8109 case 'H':
8110 s *= 3600;
8111 break;
8112 case 'd':
8113 case 'D':
8114 s *= 3600 * 24;
8115 break;
8116 }
8117
8118 return (int) s;
8119}
Here is the caller graph for this function:

◆ time_to_string()

std::string time_to_string ( time_t  t)

Definition at line 8139 of file mhttpd.cxx.

8140{
8141 char buf[256];
8142 sprintf(buf, "%.0f", (double)t);
8143 return buf;
8144}
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 13644 of file mhttpd.cxx.

13645{
13646 if (fpp)
13647 *fpp = NULL;
13648 if (!try_dir)
13649 return SS_FILE_ERROR;
13650 if (strlen(try_dir) < 1)
13651 return SS_FILE_ERROR;
13652
13653 path = try_dir;
13654 if (path[path.length()-1] != DIR_SEPARATOR)
13655 path += DIR_SEPARATOR_STR;
13656 path += filename;
13657
13658 FILE* fp = fopen(path.c_str(), "r");
13659
13660 if (trace) {
13661 if (fp)
13662 printf("file \"%s\": OK!\n", path.c_str());
13663 else
13664 printf("file \"%s\": not found.\n", path.c_str());
13665 }
13666
13667 if (!fp)
13668 return SS_FILE_ERROR;
13669 else if (fpp)
13670 *fpp = fp;
13671 else
13672 fclose(fp);
13673
13674 return SUCCESS;
13675}
Here is the caller graph for this function:

◆ Unlock()

void Unlock ( RequestTrace t)

Definition at line 12248 of file mhttpd.cxx.

12249{
12251 gMutex.unlock();
12252}
double fTimeUnlocked
Definition mhttpd.cxx:390
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 882 of file mhttpd.cxx.

886{
887 //char *px = p;
888 char *pD, str[3];
889 int i;
890
891 //printf("URL decode: [%s] --> ", p);
892
893 pD = p;
894 while (*p) {
895 if (*p == '%') {
896 /* Escape: next 2 chars are hex representation of the actual character */
897 p++;
898 if (isxdigit(p[0]) && isxdigit(p[1])) {
899 str[0] = p[0];
900 str[1] = p[1];
901 str[2] = 0;
902 sscanf(str, "%02X", &i);
903
904 *pD++ = (char) i;
905 p += 2;
906 } else
907 *pD++ = '%';
908 } else if (*p == '+') {
909 /* convert '+' to ' ' */
910 *pD++ = ' ';
911 p++;
912 } else {
913 *pD++ = *p++;
914 }
915 }
916 *pD = '\0';
917
918 //printf("[%s]\n", px);
919}
Here is the caller graph for this function:

◆ UrlDecode()

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

Definition at line 843 of file mhttpd.cxx.

847{
848 std::string s;
849
850 //printf("URL decode: [%s] --> ", p);
851
852 while (*p) {
853 if (*p == '%') {
854 /* Escape: next 2 chars are hex representation of the actual character */
855 p++;
856 if (isxdigit(p[0]) && isxdigit(p[1])) {
857 int i = 0;
858 char str[3];
859 str[0] = p[0];
860 str[1] = p[1];
861 str[2] = 0;
862 sscanf(str, "%02X", &i);
863
864 s += (char) i;
865 p += 2;
866 } else
867 s += '%';
868 } else if (*p == '+') {
869 /* convert '+' to ' ' */
870 s += ' ';
871 p++;
872 } else {
873 s += *p++;
874 }
875 }
876
877 //printf("[%s]\n", s.c_str());
878
879 return s;
880}
Here is the caller graph for this function:

◆ urlEncode() [1/2]

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

Definition at line 921 of file mhttpd.cxx.

926{
927 char *pd, *p;
928 int len = strlen(ps);
929 char *str = (char*)malloc(len*3 + 10); // at worst, each input character is expanded into 3 output characters
930
931 pd = str;
932 p = ps;
933 while (*p) {
934 if (isalnum(*p)) {
935 *pd++ = *p++;
936 } else {
937 sprintf(pd, "%%%02X", (*p)&0xFF);
938 pd += 3;
939 p++;
940 }
941 }
942 *pd = '\0';
943
944 if (/* DISABLES CODE */ (0)) {
945 printf("urlEncode [");
946 for (p=ps; *p!=0; p++)
947 printf("0x%02x ", (*p)&0xFF);
948 printf("]\n");
949
950 printf("urlEncode [%s] -> [%s]\n", ps, str);
951 }
952
953 mstrlcpy(ps, str, ps_size);
954 free(str);
955}
Here is the caller graph for this function:

◆ urlEncode() [2/2]

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

Definition at line 957 of file mhttpd.cxx.

962{
963 std::string encoded;
964
965 const char* p = text;
966 while (*p) {
967 if (isalnum(*p)) {
968 encoded += *p++;
969 } else {
970 char buf[16];
971 sprintf(buf, "%%%02X", (*p)&0xFF);
972 encoded += buf;
973 p++;
974 }
975 }
976
977 if (/* DISABLES CODE */ (0)) {
978 printf("urlEncode [");
979 for (p=text; *p!=0; p++)
980 printf("0x%02x ", (*p)&0xFF);
981 printf("]\n");
982
983 printf("urlEncode [%s] -> [%s]\n", text, encoded.c_str());
984 }
985
986 return encoded;
987}

◆ 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 7912 of file mhttpd.cxx.

7916{
7917 double dy, int_dy, frac_dy, y_act, label_dy, major_dy, y_screen, y_next;
7918 int tick_base, major_base, label_base, n_sig1, n_sig2, ys, max_width;
7919 int last_label_y;
7920 char str[80];
7921 const double base[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
7922
7923 if (ymax <= ymin || width <= 0)
7924 return 0;
7925
7926 // 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
7927 if (fabs(ymax - ymin) <= 1e-10)
7928 return 0;
7929
7930 if (logaxis) {
7931 dy = pow(10, floor(log(ymin) / LN10));
7932 label_dy = dy;
7933 major_dy = dy * 10;
7934 n_sig1 = 4;
7935 } else {
7936 dy = (ymax - ymin) / (double) (width / 5);
7937
7938 frac_dy = modf(log(dy) / LN10, &int_dy);
7939 if (frac_dy < 0) {
7940 frac_dy += 1;
7941 int_dy -= 1;
7942 }
7943
7944 tick_base = frac_dy < LOG2 ? 1 : frac_dy < LOG5 ? 2 : 3;
7945 major_base = label_base = tick_base + 1;
7946
7947 /* rounding up of dy, label_dy */
7948 dy = pow(10, int_dy) * base[tick_base];
7949 major_dy = pow(10, int_dy) * base[major_base];
7950 label_dy = major_dy;
7951
7952 /* number of significant digits */
7953 if (ymin == 0)
7954 n_sig1 = 0;
7955 else
7956 n_sig1 =
7957 (int) floor(log(fabs(ymin)) / LN10) -
7958 (int) floor(log(fabs(label_dy)) / LN10) + 1;
7959
7960 if (ymax == 0)
7961 n_sig2 = 0;
7962 else
7963 n_sig2 =
7964 (int) floor(log(fabs(ymax)) / LN10) -
7965 (int) floor(log(fabs(label_dy)) / LN10) + 1;
7966
7967 n_sig1 = MAX(n_sig1, n_sig2);
7968 n_sig1 = MAX(n_sig1, 4);
7969
7970 /* increasing label_dy, if labels would overlap */
7971 while (label_dy / (ymax - ymin) * width < 1.5 * font->h) {
7972 label_base++;
7973 label_dy = pow(10, int_dy) * base[label_base];
7974 if (label_base % 3 == 2 && major_base % 3 == 1) {
7975 major_base++;
7976 major_dy = pow(10, int_dy) * base[major_base];
7977 }
7978 }
7979 }
7980
7981 max_width = 0;
7982 y_act = floor(ymin / dy) * dy;
7983
7984 if (x1 != 0 || y1 != 0)
7985 gdImageLine(im, x1, y1, x1, y1 - width, col);
7986
7987 last_label_y = y1 + 2 * font->h;
7988
7989 do {
7990 if (logaxis)
7991 y_screen = y1 - (log(y_act) - log(ymin)) / (log(ymax) - log(ymin)) * width;
7992 else
7993 y_screen = y1 - (y_act - ymin) / (ymax - ymin) * width;
7994 ys = (int) (y_screen + 0.5);
7995
7996 if (y_screen < y1 - width - 0.001)
7997 break;
7998
7999 if (y_screen <= y1 + 0.001) {
8000 if (fabs(floor(y_act / major_dy + 0.5) - y_act / major_dy) <
8001 dy / major_dy / 10.0) {
8002 if (fabs(floor(y_act / label_dy + 0.5) - y_act / label_dy) <
8003 dy / label_dy / 10.0) {
8004 if (x1 != 0 || y1 != 0) {
8005 /* label tick mark */
8006 gdImageLine(im, x1, ys, x1 + text, ys, col);
8007
8008 /* grid line */
8009 if (grid != 0 && y_screen < y1 && y_screen > y1 - width) {
8010 if (grid > 0)
8011 gdImageLine(im, x1 + 1, ys, x1 + grid, ys, gcol);
8012 else
8013 gdImageLine(im, x1 - 1, ys, x1 + grid, ys, gcol);
8014 }
8015
8016 /* label */
8017 if (label != 0) {
8018 sprintf(str, "%1.*lG", n_sig1, y_act);
8019 if (label < 0)
8020 gdImageString(im, font, x1 + label - font->w * strlen(str),
8021 ys - font->h / 2, str, col);
8022 else
8023 gdImageString(im, font, x1 + label, ys - font->h / 2, str, col);
8024
8025 last_label_y = ys - font->h / 2;
8026 }
8027 } else {
8028 sprintf(str, "%1.*lG", n_sig1, y_act);
8029 max_width = MAX(max_width, (int) (font->w * strlen(str)));
8030 }
8031 } else {
8032 if (x1 != 0 || y1 != 0) {
8033 /* major tick mark */
8034 gdImageLine(im, x1, ys, x1 + major, ys, col);
8035
8036 /* grid line */
8037 if (grid != 0 && y_screen < y1 && y_screen > y1 - width)
8038 gdImageLine(im, x1, ys, x1 + grid, ys, col);
8039 }
8040 }
8041 if (logaxis) {
8042 dy *= 10;
8043 major_dy *= 10;
8044 label_dy *= 10;
8045 }
8046
8047 } else {
8048 if (x1 != 0 || y1 != 0) {
8049 /* minor tick mark */
8050 gdImageLine(im, x1, ys, x1 + minor, ys, col);
8051 }
8052
8053 /* for logaxis, also put labes on minor tick marks */
8054 if (logaxis) {
8055 if (label != 0) {
8056 if (x1 != 0 || y1 != 0) {
8057 /* calculate position of next major label */
8058 y_next = pow(10, floor(log(y_act) / LN10) + 1);
8059 y_screen =
8060 (int) (y1 -
8061 (log(y_next) - log(ymin)) / (log(ymax) -
8062 log(ymin)) * width + 0.5);
8063
8064 if (ys + font->h / 2 < last_label_y
8065 && ys - font->h / 2 > y_screen + font->h / 2) {
8066 sprintf(str, "%1.*lG", n_sig1, y_act);
8067 if (label < 0)
8068 gdImageString(im, font, x1 + label - font->w * strlen(str),
8069 ys - font->h / 2, str, col);
8070 else
8071 gdImageString(im, font, x1 + label, ys - font->h / 2, str,
8072 col);
8073 }
8074
8075 last_label_y = ys - font->h / 2;
8076 } else {
8077 sprintf(str, "%1.*lG", n_sig1, y_act);
8078 max_width = MAX(max_width, (int) (font->w * strlen(str)));
8079 }
8080 }
8081 }
8082 }
8083 }
8084
8085 y_act += dy;
8086
8087 /* supress 1.23E-17 ... */
8088 if (fabs(y_act) < dy / 100)
8089 y_act = 0;
8090
8091 } while (1);
8092
8093 return max_width + abs(label);
8094}
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 10084 of file mhttpd.cxx.

10085{
10086 int status = db_find_key(hDB, dir, str, hKey);
10087 if (status == DB_SUCCESS)
10088 return status;
10089
10090 db_create_key(hDB, dir, str, tid);
10091 status = db_find_key(hDB, dir, str, hKey);
10092 if (status != DB_SUCCESS || !*hKey) {
10093 cm_msg(MERROR, "xdb_find_key", "Invalid ODB path \"%s\"", str);
10094 str = "bad_xdb_find_key";
10095 db_create_key(hDB, dir, str, tid);
10096 db_find_key(hDB, dir, str, hKey);
10097 }
10098 assert(*hKey);
10099
10100 if (tid == TID_STRING) {
10101 db_set_data_index(hDB, *hKey, "", size, 0, TID_STRING);
10102 }
10103
10104 return status;
10105}
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 10068 of file mhttpd.cxx.

10069{
10070 HNDLE hKey;
10071 int status = db_find_key(hDB, 0, str, &hKey);
10072 if (status != DB_SUCCESS)
10073 return status;
10074
10075 KEY key;
10076 db_get_key(hDB, hKey, &key);
10077 if (index >= key.num_values)
10078 return DB_OUT_OF_RANGE;
10079
10080 status = db_get_data_index(hDB, hKey, value, &size, index, tid);
10081 return status;
10082}
#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 13781 of file mhttpd.cxx.

13781 {
13782 unsigned long now = (unsigned long) time(NULL);
13783 unsigned long val = (unsigned long) strtoul(nonce, NULL, 16);
13784 return now < val || now - val < 3600;
13785}
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 13792 of file mhttpd.cxx.

13793 {
13794 mg_printf(c,
13795 "HTTP/1.1 401 Unauthorized\r\n"
13796 "WWW-Authenticate: Digest qop=\"auth\", "
13797 "realm=\"%s\", nonce=\"%lu\"\r\n"
13798 "Content-Length: 0\r\n\r\n",
13799 domain, (unsigned long) time(NULL));
13800}
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 13760 of file mhttpd.cxx.

13764 {
13765 static const char colon[] = ":";
13766 static const size_t one = 1;
13767 char ha2[33];
13768
13769 cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);
13770 cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,
13771 nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,
13772 colon, one, ha2, sizeof(ha2) - 1, NULL);
13773}
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 13456 of file mhttpd.cxx.

13456{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 3473 of file mhttpd.cxx.

3473 {
3474 "Src = STRING : [256] ",
3475 "X = INT : 0",
3476 "Y = INT : 0",
3477 "Width = INT : 10",
3478 "Height = INT : 100",
3479 "Direction = INT : 0",
3480 "Axis = INT : 1",
3481 "Logscale = BOOL : n",
3482 "Min = DOUBLE : 0",
3483 "Max = DOUBLE : 10",
3484 "FGColor = STRING : [8] 000000",
3485 "BGColor = STRING : [8] FFFFFF",
3486 "BDColor = STRING : [8] 808080",
3487 NULL
3488};

◆ 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 3433 of file mhttpd.cxx.

3433 {
3434 "Src = STRING : [256] ",
3435 "Format = STRING : [32] %1.1f",
3436 "Font = STRING : [32] Medium",
3437 "X = INT : 0",
3438 "Y = INT : 0",
3439 "Align = INT : 0",
3440 "FGColor = STRING : [8] 000000",
3441 "BGColor = STRING : [8] FFFFFF",
3442 NULL
3443};

◆ 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 282 of file mhttpd.cxx.

282 {
283 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10,
284 0x10, 0x00, 0x01, 0x00, 0x04, 0x00, 0x28, 0x01,
285 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00,
286 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00,
287 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x0F,
291 0x0A, 0x00, 0x5C, 0x86, 0x4C, 0x00, 0x2F, 0x5E,
292 0x1A, 0x00, 0xBF, 0xD3, 0xD7, 0x00, 0x29, 0x17,
293 0x8D, 0x00, 0x50, 0xA7, 0xA4, 0x00, 0x59, 0x57,
294 0x7F, 0x00, 0xC6, 0xA3, 0xAC, 0x00, 0xFC, 0xFE,
295 0xFC, 0x00, 0x28, 0x12, 0x53, 0x00, 0x58, 0x7D,
296 0x72, 0x00, 0xC4, 0x3A, 0x34, 0x00, 0x3C, 0x3D,
297 0x69, 0x00, 0xC5, 0xB6, 0xB9, 0x00, 0x94, 0x92,
298 0x87, 0x00, 0x7E, 0x7A, 0xAA, 0x00, 0x88, 0x88,
299 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x81, 0x22,
300 0xD8, 0x88, 0x88, 0x88, 0xF6, 0xD8, 0x82, 0x22,
301 0xE8, 0x88, 0x88, 0x8D, 0x44, 0x98, 0x82, 0x22,
302 0xA8, 0x88, 0x88, 0x8F, 0x44, 0x48, 0x82, 0x22,
303 0x25, 0x76, 0x67, 0x55, 0x44, 0xF8, 0x88, 0x88,
304 0x3A, 0xC9, 0x9C, 0x53, 0x83, 0x88, 0x88, 0x88,
305 0x8D, 0x99, 0x99, 0x38, 0x88, 0x88, 0x88, 0x88,
306 0x88, 0x99, 0x9C, 0x88, 0x88, 0x88, 0x88, 0x88,
307 0x88, 0xF9, 0x9D, 0x88, 0x88, 0x88, 0x88, 0x88,
308 0x88, 0x8A, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88,
309 0x88, 0x85, 0xD8, 0x88, 0x88, 0x88, 0x88, 0x88,
310 0x88, 0xEA, 0xAE, 0x88, 0x88, 0x88, 0x88, 0x88,
311 0x88, 0x00, 0x0B, 0x88, 0x88, 0x88, 0x88, 0x88,
312 0x88, 0x70, 0x0D, 0x88, 0x88, 0x88, 0x88, 0x88,
313 0x88, 0x87, 0xD8, 0x88, 0x88, 0x88, 0x88, 0x88,
314 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
323};

◆ 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, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68,
222 0x36, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4D,
223 0x45, 0x07, 0xD4, 0x0B, 0x1A, 0x08, 0x37, 0x07,
224 0x0D, 0x7F, 0x16, 0x5C, 0x00, 0x00, 0x00, 0x09,
225 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2E, 0x23,
226 0x00, 0x00, 0x2E, 0x23, 0x01, 0x78, 0xA5, 0x3F,
227 0x76, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D,
228 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61,
229 0x05, 0x00, 0x00, 0x01, 0x7D, 0x49, 0x44, 0x41,
230 0x54, 0x78, 0xDA, 0x63, 0xFC, 0xFF, 0xFF, 0x3F,
231 0x03, 0x29, 0x80, 0x09, 0xAB, 0xE8, 0xD2, 0x65,
232 0x77, 0x36, 0x6F, 0x7E, 0x8A, 0x5D, 0xC7, 0x7F,
233 0x0C, 0x30, 0x67, 0xEE, 0x0D, 0x56, 0xCE, 0xCD,
234 0x5C, 0xBC, 0x3B, 0xB6, 0x6D, 0x7F, 0x81, 0x29,
235 0xCB, 0x88, 0xE6, 0x24, 0x20, 0x57, 0x50, 0x7C,
236 0xDD, 0xCF, 0x1F, 0x6C, 0x40, 0xCB, 0xB5, 0xB5,
237 0x05, 0xCF, 0x1C, 0xB7, 0x42, 0xB3, 0x80, 0x05,
238 0x8D, 0xCF, 0xC8, 0xC8, 0x58, 0x5A, 0x2A, 0xFB,
239 0xF6, 0x4D, 0x37, 0x1B, 0xAB, 0xA0, 0xB4, 0x4C,
240 0x0A, 0x51, 0x4E, 0x02, 0x82, 0x85, 0xCB, 0x12,
241 0x0E, 0x1D, 0xAB, 0xC7, 0x2A, 0xC5, 0x82, 0x69,
242 0xC4, 0xAF, 0x5F, 0x7F, 0x1E, 0x3F, 0xF8, 0xCD,
243 0xCB, 0xF1, 0xF5, 0xEF, 0xDF, 0x7F, 0xCC, 0xCC,
244 0x4C, 0x84, 0x6D, 0x98, 0x59, 0xD5, 0xEB, 0xCF,
245 0xA5, 0x16, 0xC4, 0xAB, 0x71, 0x72, 0xCB, 0x21,
246 0x4C, 0x59, 0x74, 0x03, 0x5E, 0x3F, 0x7F, 0xB3,
247 0x6B, 0xD6, 0x22, 0x46, 0xA6, 0x7F, 0x0C, 0x0C,
248 0x7F, 0xD7, 0x75, 0x4D, 0xFB, 0xF1, 0xFD, 0x27,
249 0x81, 0x78, 0xB8, 0x7D, 0xE9, 0x0A, 0xCB, 0xFF,
250 0xDF, 0x4C, 0x8C, 0x8C, 0x40, 0xF6, 0xAD, 0x4B,
251 0x67, 0x1F, 0xDE, 0xBD, 0x8B, 0x45, 0x03, 0x3C,
252 0x60, 0x8F, 0x9D, 0xD8, 0xB3, 0xEB, 0x74, 0xB5,
253 0x90, 0x26, 0x07, 0x03, 0x48, 0xE4, 0x3F, 0x8F,
254 0xF6, 0xFF, 0x1B, 0x0F, 0x9A, 0x1E, 0x3E, 0x3A,
255 0xFB, 0xF3, 0xDB, 0x8F, 0xB7, 0x0F, 0x9E, 0x43,
256 0x83, 0xF1, 0xCF, 0xDF, 0x3F, 0x8A, 0x29, 0xCE,
257 0x3F, 0x7F, 0xFD, 0xFC, 0xCF, 0xF0, 0xDF, 0x98,
258 0xE9, 0xB5, 0x8F, 0xBD, 0x8A, 0x3C, 0x6F, 0xEC,
259 0xB9, 0x2D, 0x47, 0xFE, 0xFC, 0xFF, 0x6F, 0x16,
260 0x6C, 0xF3, 0xEC, 0xD3, 0x1C, 0x2E, 0x96, 0xEF,
261 0xBF, 0xAB, 0x7E, 0x32, 0x7D, 0xE2, 0x10, 0xCE,
262 0x88, 0xF4, 0x69, 0x2B, 0x60, 0xFC, 0xF4, 0xF5,
263 0x97, 0x78, 0x8A, 0x36, 0xD8, 0x44, 0x86, 0x18,
264 0x0D, 0xD7, 0x29, 0x95, 0x13, 0xD8, 0xD9, 0x58,
265 0xE1, 0x0E, 0xF8, 0xF1, 0xF3, 0xDB, 0xC6, 0xD6,
266 0xEC, 0x5F, 0x53, 0x8E, 0xBF, 0xFE, 0xC3, 0x70,
267 0x93, 0x8D, 0x6D, 0xDA, 0xCB, 0x0B, 0x4C, 0x3F,
268 0xFF, 0xFC, 0xFA, 0xCF, 0x0C, 0xB4, 0x09, 0x84,
269 0x54, 0xD5, 0x74, 0x91, 0x55, 0x03, 0x01, 0x07,
270 0x3B, 0x97, 0x96, 0x6E, 0xC8, 0x17, 0xFE, 0x7F,
271 0x4F, 0xF8, 0xFE, 0xBC, 0x95, 0x16, 0x60, 0x62,
272 0x62, 0x64, 0xE1, 0xE6, 0x60, 0x73, 0xD1, 0xB2,
273 0x7A, 0xFA, 0xE2, 0xF1, 0xDF, 0x3F, 0xFF, 0xC4,
274 0x78, 0x44, 0x31, 0xA3, 0x45, 0x2B, 0xD0, 0xE3,
275 0xF6, 0xD9, 0xE3, 0x2F, 0x2E, 0x9D, 0x29, 0xA9,
276 0xAC, 0x07, 0xA6, 0x03, 0xF4, 0xB4, 0x44, 0x10,
277 0x00, 0x00, 0x75, 0x65, 0x12, 0xB0, 0x49, 0xFF,
278 0x3F, 0x68, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
279 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
280};

◆ gAllowedHosts

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

Definition at line 13468 of file mhttpd.cxx.

◆ gAuthMg

Auth* gAuthMg = NULL
static

Definition at line 13758 of file mhttpd.cxx.

◆ gDoReloadHistory

bool gDoReloadHistory = false
static

Definition at line 8149 of file mhttpd.cxx.

◆ gDoSetupHistoryWatch

bool gDoSetupHistoryWatch = true
static

Definition at line 8148 of file mhttpd.cxx.

◆ gMh

MidasHistoryInterface* gMh = NULL
static

Definition at line 8158 of file mhttpd.cxx.

◆ gMhkey

HNDLE gMhkey = 0
static

Definition at line 8159 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 506 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 435 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 13710 of file mhttpd.cxx.

◆ trace_mg_recv

bool trace_mg_recv = false
static

Definition at line 13711 of file mhttpd.cxx.

◆ trace_mg_send

bool trace_mg_send = false
static

Definition at line 13712 of file mhttpd.cxx.

◆ trace_mg_verbose

bool trace_mg_verbose = false
static

Definition at line 13713 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 13709 of file mhttpd.cxx.