]> jfr.im git - irc/quakenet/newserv.git/blobdiff - dbapi2/dbapi2.c
TRUSTS: require sqlite
[irc/quakenet/newserv.git] / dbapi2 / dbapi2.c
index d6ca8bed73e8fea7d5787e1995737b7c4cde0fef..a960b74c9e0fd1b5cfe778497d8c9541e7ff6faa 100644 (file)
@@ -147,6 +147,32 @@ static void dbsafesimplequery(const DBAPIConn *db, const char *format, const cha
   db->__query(db, NULL, NULL, buf);
 }
 
+static void dbloadtable(const DBAPIConn *db, DBAPIQueryCallback init, DBAPIQueryCallback data, DBAPIQueryCallback fini, DBAPIUserData tag, const char *tablename) {
+  db->__loadtable(db, init, data, fini, tag, db->tablename(db, tablename));
+}
+
+static void dbcall(const DBAPIConn *db, DBAPIQueryCallback cb, DBAPIUserData data, const char *function, const char *format, const char *types, ...) {
+  va_list ap;
+  char buf[QUERYBUFLEN];
+
+  va_start(ap, types);
+  dbvsnprintf(db, buf, sizeof(buf), format, types, ap);
+  va_end(ap);
+
+  db->__call(db, cb, data, function, buf);
+}
+
+static void dbsimplecall(const DBAPIConn *db, const char *function, const char *format, const char *types, ...) {
+  va_list ap;
+  char buf[QUERYBUFLEN];
+
+  va_start(ap, types);
+  dbvsnprintf(db, buf, sizeof(buf), format, types, ap);
+  va_end(ap);
+
+  db->__call(db, NULL, NULL, function, buf);
+}
+
 DBAPIConn *dbapi2open(const char *provider, const char *database) {
   int i, found = -1;
   DBAPIConn *db;
@@ -187,17 +213,21 @@ DBAPIConn *dbapi2open(const char *provider, const char *database) {
   db->query = dbsafequery;
   db->createtable = dbsafecreatetable;
   db->squery = dbsafesimplequery;
-  db->loadtable = p->loadtable;
+  db->loadtable = dbloadtable;
   db->escapestring = p->escapestring;
   db->tablename = p->tablename;
   db->unsafequery = dbunsafequery;
   db->unsafesquery = dbunsafesimplequery;
   db->unsafecreatetable = dbunsafecreatetable;
+  db->call = dbcall;
+  db->scall = dbsimplecall;
 
   db->__query = p->query;
   db->__close = p->close;
   db->__quotestring = p->quotestring;
   db->__createtable = p->createtable;
+  db->__loadtable = p->loadtable;
+  db->__call = p->call;
 
   strlcpy(db->name, database, DBNAME_LEN);
 
@@ -251,7 +281,8 @@ static void dbvsnprintf(const DBAPIConn *db, char *buf, size_t size, const char
       switch(*types) {
         case 's':
           s = va_arg(ap, char *);
-          l = strlen(s);
+          if(s)
+            l = strlen(s);
           fallthrough = 1;
 
         /* falling through */
@@ -261,8 +292,10 @@ static void dbvsnprintf(const DBAPIConn *db, char *buf, size_t size, const char
             l = va_arg(ap, size_t);
           }
 
-          /* now... this is a guess, but we should catch it most of the time */
-          if((l > (VSNPF_MAXARGLEN / 2)) || !db->__quotestring(db, cb, sizeof(convbuf[0]), s, l)) {
+          if(!s) {
+            strlcpy(cb, "NULL", sizeof(convbuf[0]));
+          } else if((l > (VSNPF_MAXARGLEN / 2)) || !db->__quotestring(db, cb, sizeof(convbuf[0]), s, l)) {
+            /* now... this is a guess, but we should catch it most of the time */
             Error("dbapi2", ERR_STOP, "Long string truncated, format: '%s', database: %s", format, db->name);
             l = VSNPF_MAXARGLEN;
           }
@@ -312,7 +345,10 @@ static void dbvsnprintf(const DBAPIConn *db, char *buf, size_t size, const char
   sbinit(&b, buf, size);
 
   for(arg=0,p=format;*p;p++) {
-    if(*p != '?') {
+    if (*p == '\\' && *(p + 1) == '?')
+      continue;
+
+    if((p != format && *(p - 1) == '\\') || *p != '?') {
       if(!sbaddchar(&b, *p))
         break;
       continue;