diff db.c @ 0:9dab44dcb331

Initial commit of Greg's code from http://www.lemis.com/grog/tmp/wh1080.tar.gz
author Daniel O'Connor <darius@dons.net.au>
date Tue, 09 Feb 2010 13:44:25 +1030
parents
children 9da35e705144
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/db.c	Tue Feb 09 13:44:25 2010 +1030
@@ -0,0 +1,247 @@
+/*
+ * Report weather conditions to remote web sites.
+ * Database access and startup functions.
+ *
+ * Greg Lehey, 14 December 2009
+ *
+ * $Id: db.c,v 1.5 2010/02/04 03:50:35 grog Exp $
+ */
+
+#include "wh1080.h"
+
+#define STAMPSIZE 32                            /* size of time stamp to print out */
+
+/* Command line options */
+int debug;                                      /* -d */
+int update = 1;                                 /* -n turns updating off  */
+int recover = 0;                                /* -r: recover missed archive data (wh1080 only) */
+int verbose;                                    /* -v */
+int once;                                       /* -1 */
+
+struct passwd *mypasswd;                        /* password information for default user */
+
+/* MySQL stuff */
+MYSQL *mysql;
+MYSQL_RES *mysql_result;
+MYSQL_ROW mysql_row;
+char mysql_querytext [1024];                    /* build up queries here */
+struct config config;
+
+void db_login ()
+{
+  if (! mysql_init (mysql))
+  {
+    fprintf (stderr, "Can't initialize MySQL\n");
+    exit (1);
+  }
+  mysql = mysql_init (mysql);
+  if (! mysql)
+  {
+    fprintf (stderr, "Can't initialize MySQL: insufficient memory\n");
+    exit (1);
+  }
+  if (! mysql_real_connect (mysql,              /* DB state */
+                            config.db_host,     /* database host */
+                            config.db_user,
+                            config.db_passwd,
+                            config.db,
+                            0,
+                            NULL,
+                            0 ))
+  {
+    fprintf (stderr,
+             "Can't connect to databaase: %s (%d)\n",
+             mysql_error (mysql),
+             mysql_errno (mysql) );
+    exit (1);
+  }
+}
+
+/*
+ * Perform a database query, return result to myresult.
+ */
+int domyquery (char *query, MYSQL_RES **myresult)
+{
+  if (mysql_query (mysql, query))
+  {
+    fprintf (stderr,
+             "Can't query database: %s (%d)\n"
+             "  query:%s\n",
+             mysql_error (mysql),
+             mysql_errno (mysql),
+             query );
+    return 1;
+  }
+  *myresult = mysql_store_result (mysql);
+  return 0;
+}
+
+/*
+ * Perform a database query, return result to implicit mysql_result.
+ */
+int doquery (char *query)
+{
+  return domyquery (query, &mysql_result);
+}
+
+/*
+ * Make a copy of a string in malloced memory and return it.
+ */
+char *mycopy (char *string)
+{
+  char *result = malloc (strlen (string) + 1);
+  strcpy (result, string);
+  return result;
+}
+
+/*
+ * Read in config from database.
+ *
+ * XXX We have a chicken and egg problem here: the config information includes
+ * the database name, but we need to know that before we start.  For the time
+ * being we supply necessary information on the command line, with defaults.
+ * FIXME.
+ */
+int read_config (int argc, char *argv [])
+{
+  int col;
+  int arg;
+
+  for (arg = 1; arg < argc; arg++)
+  {
+    if (! strcmp (argv [arg], "-d"))
+      debug = 1;
+    else if (! strcmp (argv [arg], "-n"))       /* turn off DB updates */
+      update = 0;
+    else if (! strcmp (argv [arg], "-v"))       /* verbose */
+      verbose = 1;
+    else if (! strcmp (argv [arg], "-1"))       /* run once and exit */
+      once = 1;
+    else
+    {
+      if (! config.station_id)
+        config.station_id = argv [arg];
+      else if (! config.db_user)
+        config.db_user = argv [arg];
+      else if (! config.db_passwd)
+        config.db_passwd = argv [arg];
+      else if (! config.db_host)
+        config.db_host = argv [arg];
+      else if (! config.db)
+        config.db = argv [arg];
+      else
+      {
+        fprintf (stderr, "Too many arguments: %s\n", argv [arg]);
+        return -1;
+      }
+    }
+  }
+
+    /* Set default values for config stuff above. */
+  if (! config.station_id)
+    config.station_id = "mystation";
+  if (! config.db_host)
+    config.db_host = "localhost";
+  if (! config.db_user)
+  {
+    /* Find out user name and use it */
+    mypasswd = getpwuid (getuid ());
+    if (mypasswd)
+      config.db_user = mycopy (mypasswd->pw_name);
+    else
+    {
+      fprintf (stderr, "Can't get default user id\n");
+      exit (1);
+    }
+  }
+  if (! config.db_passwd)
+    config.db_passwd = "";
+  if (! config.db)
+    config.db = "weather";
+
+  if (! mysql_init (mysql))
+  {
+    fprintf (stderr, "Can't initialize MySQL\n");
+    exit (1);
+  }
+  mysql = mysql_init (mysql);
+  if (! mysql)
+  {
+    fprintf (stderr, "Can't initialize MySQL: insufficient memory\n");
+    exit (1);
+  }
+  if (! mysql_real_connect (mysql,              /* DB state */
+                            config.db_host,     /* database host */
+                            config.db_user,
+                            config.db_passwd,
+                            config.db,
+                            0,
+                            NULL,
+                            0 ))
+  {
+    fprintf (stderr,
+             "Can't connect to databaase: %s (%d)\n",
+             mysql_error (mysql),
+             mysql_errno (mysql) );
+    exit (1);
+  }
+
+  /*
+   * Read the rest of the config from specified database.
+   */
+
+  sprintf (mysql_querytext,
+           "SELECT version,\n"
+           "       latitude,\n"
+           "       longitude,\n"
+           "       elevation,\n"
+           "       pressure_error,\n"
+           "       poll_interval,\n"
+           "       address,\n"
+           "       wunderground_station_id,\n"
+           "       wunderground_passwd,\n"
+           "       wunderground_report_interval,\n"
+           "       weatheforyou_station_id,\n"
+           "       weatheforyou_passwd,\n"
+           "       weatherforyou_report_interval,\n"
+           "       website_generation_interval,\n"
+           "       db_table,\n"
+           "       php_header,\n"
+           "       comparefile\n"
+           "FROM config\n"
+           "WHERE station_id = \"%s\";\n",
+           config.station_id );
+  if (doquery (mysql_querytext))                /* failure */
+    exit (1);
+
+  if (! (mysql_row = mysql_fetch_row (mysql_result))) /* got something */
+  {
+    fprintf (stderr, "No configuration file found\n");
+    exit (1);
+  }
+
+  /*
+   * XXX here we should perform a version check.  Do it when we introduce
+   * version 2.
+   */
+  /* And this is filthy ugly.  Fix it */
+  col = 1;
+  config.latitude = atof (mysql_row [col++]);
+  config.longitude = atof (mysql_row [col++]);
+  config.elevation = atof (mysql_row [col++]);  /* metres */
+  config.pressure_error = atof (mysql_row [col++]); /* difference between actual and real pressure, hPa */
+  config.poll_interval = atoi (mysql_row [col++]); /* time, in seconds, between reading the device */
+  config.address = mycopy (mysql_row [col++]);  /* Address to display on web pages */
+  config.wunderground_station_id = mycopy (mysql_row [col++]);
+  config.wunderground_passwd = mycopy (mysql_row [col++]);
+  config.wunderground_report_interval = atoi (mysql_row [col++]); /* how many seconds between reports to Wunderground */
+  config.weatheforyou_station_id = mycopy (mysql_row [col++]);
+  config.weatheforyou_passwd = mycopy (mysql_row [col++]);
+  config.weatherforyou_report_interval = atoi (mysql_row [col++]); /* how many seconds between reports to Weather for you */
+  config.website_generation_interval = atoi (mysql_row [col++]); /* how many seconds between generating PHP header file */
+  config.db_table = mycopy (mysql_row [col++]); /* table */
+  config.php_header = mycopy (mysql_row [col++]); /* php header file with weather data */
+  config.comparefile = mycopy (mysql_row [col++]); /* file to compare local weather stations */
+  return 0;                                     /* success */
+}
+