Check-in [b44d4a89d0]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Refactoring some of the configuration sync logic in preparation for bigger changes.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b44d4a89d0f0a3eb8965cbd7fa462b813d818e36
User & Date: drh 2011-04-25 16:57:03.640
Context
2011-04-25
20:10
Further work toward two-way configuration sync. Need to check in these changes before they are complete in order to deal with another issue. check-in: 71fc181fee user: drh tags: trunk
16:57
Refactoring some of the configuration sync logic in preparation for bigger changes. check-in: b44d4a89d0 user: drh tags: trunk
2011-04-22
13:49
Fix the is_a_leaf() function so that it correctly identifies nodes as leaves if they have no non-merge children in the same branch. check-in: 0a89d03cf6 user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/configure.c.
288
289
290
291
292
293
294


































295
296
297
298
299
300
301
         flag_test_function, 0, 0);
    sqlite3_create_function(g.db, "flag_clear", 1, SQLITE_UTF8, 0,
         flag_clear_function, 0, 0);
    flag_value = 0xffff;
    db_multi_exec(zSQL2);
  }
}



































/*
** After receiving configuration data, call this routine to transfer
** the results into the main database.
*/
void configure_finalize_receive(void){
  static const char zSQL[] =







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
         flag_test_function, 0, 0);
    sqlite3_create_function(g.db, "flag_clear", 1, SQLITE_UTF8, 0,
         flag_clear_function, 0, 0);
    flag_value = 0xffff;
    db_multi_exec(zSQL2);
  }
}

/*
** Process a single "config" card received from the other side of a
** sync session.
**
** Mask consists of one or more CONFIGSET_* values ORed together, to
** designate what types of configuration we are allowed to receive.
*/
void configure_receive(const char *zName, Blob *pContent, int mask){
  if( (configure_is_exportable(zName) & mask)==0 ) return;
  if( strcmp(zName, "logo-image")==0 ){
    Stmt ins;
    db_prepare(&ins,
      "REPLACE INTO config(name, value) VALUES(:name, :value)"
    );
    db_bind_text(&ins, ":name", zName);
    db_bind_blob(&ins, ":value", pContent);
    db_step(&ins);
    db_finalize(&ins);
  }else if( zName[0]=='@' ){
    /* Notice that we are evaluating arbitrary SQL received from the
    ** client.  But this can only happen if the client has authenticated
    ** as an administrator, so presumably we trust the client at this
    ** point.
    */
    db_multi_exec("%s", blob_str(pContent));
  }else{
    db_multi_exec(
       "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
       zName, blob_str(pContent)
    );
  }
}


/*
** After receiving configuration data, call this routine to transfer
** the results into the main database.
*/
void configure_finalize_receive(void){
  static const char zSQL[] =
Changes to src/xfer.c.
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
      blob_extract(xfer.pIn, size, &content);
      if( !g.okAdmin ){
        cgi_reset_content();
        @ error not\sauthorized\sto\spush\sconfiguration
        nErr++;
        break;
      }
      if( zName[0]!='@' ){
        if( strcmp(zName, "logo-image")==0 ){
          Stmt ins;
          db_prepare(&ins,
            "REPLACE INTO config(name, value) VALUES(:name, :value)"
          );
          db_bind_text(&ins, ":name", zName);
          db_bind_blob(&ins, ":value", &content);
          db_step(&ins);
          db_finalize(&ins);
        }else{
          db_multi_exec(
              "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
              zName, blob_str(&content)
          );
        }
      }else{
        /* Notice that we are evaluating arbitrary SQL received from the
        ** client.  But this can only happen if the client has authenticated
        ** as an administrator, so presumably we trust the client at this
        ** point.
        */
        if( !recvConfig ){
          configure_prepare_to_receive(0);
          recvConfig = 1;
        }
        db_multi_exec("%s", blob_str(&content));
      }
      blob_reset(&content);
      blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
    }else

      

    /*    cookie TEXT







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<







1050
1051
1052
1053
1054
1055
1056






















1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067
1068
      blob_extract(xfer.pIn, size, &content);
      if( !g.okAdmin ){
        cgi_reset_content();
        @ error not\sauthorized\sto\spush\sconfiguration
        nErr++;
        break;
      }






















      if( !recvConfig ){
        configure_prepare_to_receive(0);
        recvConfig = 1;
      }
      configure_receive(zName, &content, CONFIGSET_ALL);

      blob_reset(&content);
      blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
    }else

      

    /*    cookie TEXT
1543
1544
1545
1546
1547
1548
1549



1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
        if( cloneSeqno>0 ) blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
        nCardSent++;
      }else
      
      /*   config NAME SIZE \n CONTENT
      **
      ** Receive a configuration value from the server.



      */
      if( blob_eq(&xfer.aToken[0],"config") && xfer.nToken==3
          && blob_is_int(&xfer.aToken[2], &size) ){
        const char *zName = blob_str(&xfer.aToken[1]);
        Blob content;
        blob_zero(&content);
        blob_extract(xfer.pIn, size, &content);
        g.okAdmin = g.okRdAddr = 1;
        if( configure_is_exportable(zName) & origConfigRcvMask ){
          if( zName[0]!='@' ){
            if( strcmp(zName, "logo-image")==0 ){
              Stmt ins;
              db_prepare(&ins,
                "REPLACE INTO config(name, value) VALUES(:name, :value)"
              );
              db_bind_text(&ins, ":name", zName);
              db_bind_blob(&ins, ":value", &content);
              db_step(&ins);
              db_finalize(&ins);
            }else{
              db_multi_exec(
                  "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
                  zName, blob_str(&content)
              );
            }
          }else{
            /* Notice that we are evaluating arbitrary SQL received from the
            ** server.  But this can only happen if we have specifically
            ** requested configuration information from the server, so
            ** presumably the operator trusts the server.
            */
            db_multi_exec("%s", blob_str(&content));
          }
        }
        nCardSent++;
        blob_reset(&content);
        blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
      }else

      
      /*    cookie TEXT







>
>
>








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538

























1539
1540
1541
1542
1543
1544
1545
        if( cloneSeqno>0 ) blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
        nCardSent++;
      }else
      
      /*   config NAME SIZE \n CONTENT
      **
      ** Receive a configuration value from the server.
      **
      ** The received configuration setting is silently ignored if it was
      ** not requested by a prior "reqconfig" sent from client to server.
      */
      if( blob_eq(&xfer.aToken[0],"config") && xfer.nToken==3
          && blob_is_int(&xfer.aToken[2], &size) ){
        const char *zName = blob_str(&xfer.aToken[1]);
        Blob content;
        blob_zero(&content);
        blob_extract(xfer.pIn, size, &content);
        g.okAdmin = g.okRdAddr = 1;
        configure_receive(zName, &content, origConfigRcvMask);

























        nCardSent++;
        blob_reset(&content);
        blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
      }else

      
      /*    cookie TEXT