16
16
#include < sys/times.h>
17
17
#include < vector>
18
18
#include < fstream>
19
+ #include < sstream>
19
20
#include < cassert>
20
21
#include < cstdlib>
21
22
#include < cstdio>
@@ -58,6 +59,7 @@ extern "C" {
58
59
}
59
60
60
61
#include " nsscommon.h"
62
+ #include " cscommon.h"
61
63
#endif // HAVE_NSS
62
64
63
65
using namespace std ;
@@ -819,7 +821,12 @@ compile_server_client::initialize ()
819
821
int
820
822
compile_server_client::create_request ()
821
823
{
822
- int rc = 0 ;
824
+ // Add the current protocol version.
825
+ ostringstream protocol_version;
826
+ protocol_version << CURRENT_CS_PROTOCOL_VERSION << " (0x" << hex << CURRENT_CS_PROTOCOL_VERSION << " )" ;
827
+ int rc = write_to_file (client_tmpdir + " /version" , protocol_version.str ());
828
+ if (rc != 0 )
829
+ return rc;
823
830
824
831
// Add the script file or script option
825
832
if (s.script_file != " " )
@@ -1302,8 +1309,29 @@ compile_server_client::unpack_response ()
1302
1309
if (rc != 0 )
1303
1310
{
1304
1311
clog << _F (" Unable to unzip the server response '%s'\n " , server_zipfile.c_str ());
1312
+ return rc;
1305
1313
}
1306
1314
1315
+ // Determine the server protocol version.
1316
+ server_version = CS_PROTOCOL_VERSION (1 , 0 ); // Assumed until discovered otherwise
1317
+ string filename = server_tmpdir + " /version" ;
1318
+ if (file_exists (filename))
1319
+ read_from_file (filename, server_version);
1320
+
1321
+ // Make sure we can communicate with this server.
1322
+ bool compatible = client_server_compatible (CURRENT_CS_PROTOCOL_VERSION, server_version);
1323
+ if (s.verbose > 1 || ! compatible)
1324
+ clog << _F (" Server protocol version is 0x%x\n " , server_version);
1325
+ if (! compatible)
1326
+ {
1327
+ clog << _F (" Unable to communicate with a server using protocol version 0x%x" ,
1328
+ server_version);
1329
+ return 1 ;
1330
+ }
1331
+
1332
+ // Warn about the shortcomings of this server if it is down level.
1333
+ show_server_compatibility (server_version);
1334
+
1307
1335
// If the server's response contains a systemtap temp directory, move
1308
1336
// its contents to our temp directory.
1309
1337
glob_t globbuf;
@@ -1316,7 +1344,8 @@ compile_server_client::unpack_response ()
1316
1344
if (globbuf.gl_pathc > 1 )
1317
1345
{
1318
1346
clog << _ (" Incorrect number of files in server response" ) << endl;
1319
- rc = 1 ; goto done;
1347
+ rc = 1 ;
1348
+ goto done;
1320
1349
}
1321
1350
1322
1351
assert (globbuf.gl_pathc == 1 );
@@ -1344,26 +1373,31 @@ compile_server_client::unpack_response ()
1344
1373
if (rc != 0 )
1345
1374
{
1346
1375
clog << _F (" Unable to link '%s' to '%s':%s\n " ,
1347
- oldname.c_str (), newname.c_str (), strerror (errno));
1376
+ oldname.c_str (), newname.c_str (), strerror (errno));
1348
1377
goto done;
1349
1378
}
1350
1379
}
1351
1380
}
1352
1381
}
1353
1382
1354
- // Remove the output line due to the synthetic server-side -k
1355
- // Look for a message containing the name of the temporary directory.
1356
- // We can't key on the message text, because it may not always be in English, so
1357
- // instead, look for the quoted directory name.
1383
+ // If the server version is less that 1.1, remove the output line due to the synthetic
1384
+ // server-side -k. Look for a message containing the name of the temporary directory.
1385
+ // We can look for the English message since server versions before 1.1 do not support
1386
+ // localization.
1387
+ if (server_version < CS_PROTOCOL_VERSION (1 , 1 ))
1388
+ {
1389
+ cmd.clear ();
1390
+ cmd.push_back (" sed" );
1391
+ cmd.push_back (" -i" );
1392
+ cmd.push_back (" /^Keeping temporary directory.*/ d" );
1393
+ cmd.push_back (server_tmpdir + " /stderr" );
1394
+ stap_system (s.verbose , cmd);
1395
+ }
1396
+
1397
+ // Remove the output line due to the synthetic server-side -p4
1358
1398
cmd.clear ();
1359
1399
cmd.push_back (" sed" );
1360
1400
cmd.push_back (" -i" );
1361
- cmd.push_back (" /^Keeping temporary directory.*/ d" ); // XXX: THIS DOES NOT WORK FOR NON-ENGLISH
1362
- cmd.push_back (server_tmpdir + " /stderr" );
1363
- stap_system (s.verbose , cmd);
1364
-
1365
- // Remove the output line due to the synthetic server-side -p4
1366
- cmd.erase (cmd.end () - 2 , cmd.end ());
1367
1401
cmd.push_back (" /^.*\\ .ko$/ d" );
1368
1402
cmd.push_back (server_tmpdir + " /stdout" );
1369
1403
stap_system (s.verbose , cmd);
@@ -1477,8 +1511,9 @@ compile_server_client::read_from_file (const string &fname, int &data)
1477
1511
return 1 ; // Failure
1478
1512
}
1479
1513
1514
+ template <class T >
1480
1515
int
1481
- compile_server_client::write_to_file (const string &fname, const string &data)
1516
+ compile_server_client::write_to_file (const string &fname, const T &data)
1482
1517
{
1483
1518
// C++ streams may not set errno in the even of a failure. However if we
1484
1519
// set it to 0 before each operation and it gets set during the operation,
@@ -1548,6 +1583,19 @@ compile_server_client::flush_to_stream (const string &fname, ostream &o)
1548
1583
clog << _ (" unknown error" ) << endl;
1549
1584
return 1 ; // Failure
1550
1585
}
1586
+
1587
+ void
1588
+ compile_server_client::show_server_compatibility (int server_version)
1589
+ {
1590
+ // Locale sensitivity was added in version 1.1
1591
+ if (server_version < CS_PROTOCOL_VERSION (1 , 1 ))
1592
+ {
1593
+ if (s.verbose <= 1 ) // this message already printed?
1594
+ clog << _F (" Server protocol version is 0x%x\n " , server_version);
1595
+ clog << _ (" The server does not use localization information passed by the client\n " );
1596
+ }
1597
+ }
1598
+
1551
1599
#endif // HAVE_NSS
1552
1600
1553
1601
// Utility Functions.
0 commit comments