aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/sledjchisl/sledjchisl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sledjchisl/sledjchisl.c')
-rw-r--r--src/sledjchisl/sledjchisl.c581
1 files changed, 363 insertions, 218 deletions
diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c
index 8b63866..057e5c3 100644
--- a/src/sledjchisl/sledjchisl.c
+++ b/src/sledjchisl/sledjchisl.c
@@ -1090,11 +1090,11 @@ struct _simList
1090{ 1090{
1091 int len, num; 1091 int len, num;
1092 char **sims; 1092 char **sims;
1093 qtreetbl_t *byTab, *simsLua; 1093 qtreetbl_t *byTab, *simsLua, *unsorted;
1094 // Stuff for the looping through sims doing things and waiting. 1094 // Stuff for the looping through sims, doing things, and waiting.
1095 char *target; 1095 int doIt;
1096 float la; 1096 float la;
1097 int doWait; 1097 char *target;
1098}; 1098};
1099simList *ourSims = NULL; 1099simList *ourSims = NULL;
1100 1100
@@ -1163,86 +1163,201 @@ static int filterInis(struct dirtree *node)
1163 return 0; 1163 return 0;
1164} 1164}
1165 1165
1166// Get the details from all the .ini or .shini sim files. 1166static int filterShinis(struct dirtree *node)
1167// Creates the .shini and sims.lua files if it's an old install. 1167{
1168// TODO - read the .shini and if it exists. 1168 if (!node->parent) return DIRTREE_RECURSE | DIRTREE_SHUTUP;
1169/* 1169 int l = strlen(node->name);
1170ourSims shall be - 1170 if ((6 < l) && ((strncmp(&(node->name[l - 6]), ".shini", 6) == 0)))
1171 int len, num; 1171 {
1172 char **sims; 1172 simList *list = (simList *) node->parent->extra;
1173 qtreetbl_t *byTab, *simsLua;
1174
1175byTab has the short name as the key, simData as the value.
1176 Iterate through it looking for target sims if specified in the sledjchisl arguments.
1177 Which can be short name, long name, foo.shini file name.
1178 Though short name is a direct lookup, and "foo.shini" we can strip off the .shini and direct lookup the short name.
1179 So only need to iterate if it's a long name.
1180 Keep in mind the argument might be a user name for IAR backups. Or perhaps a UUID.
1181
1182**sims will be in sims.lua order, and maybe include a pointer to the simData.
1183 We really only need to iterate through this at full start up and reverse iterate through it at full shutdown.
1184 So just the tab names in the correct order is fine.
1185
1186
1187if sims.lua doesn't exist
1188 create blank one
1189else
1190 read it
1191loop through old config/sim*
1192 if it's not a *.shini file
1193 read *.ini
1194 create *.shini
1195 write *.shini
1196 else
1197 read the *.shini file
1198 add *.shini to ourSims
1199 if it's not in sims.lua, add it to unsorted
1200write sims.lua if it changed
1201reorder **sims
1202 1173
1203*/ 1174 if ((list->num + 1) > list->len)
1204simList *getSims() 1175 {
1176 list->len = list->len + 1;
1177 list->sims = xrealloc(list->sims, list->len * sizeof(char *));
1178 }
1179 list->sims[list->num] = xstrndup(node->name, l - 6);
1180 list->num++;
1181 }
1182 return 0;
1183}
1184
1185////////////////////////////////////////////////////////////////////////////////////////////////////
1186// Sim wrangling loop.
1187////////////////////////////////////////////////////////////////////////////////////////////////////
1188typedef void (*simFunction)(simData *simd, char *sim, char *type, int count, int window, int panes, int pane);
1189void forEachSim(char *verb, simFunction func, simFunction not)
1205{ 1190{
1206 if (NULL != ourSims) return ourSims; 1191 qtreetbl_obj_t obj0, obj1;
1192 qLua *q0, *q1;
1193 int count = 0, window = 0, panes = 4, pane = 0;
1207 1194
1208 char *path = xmprintf("%s/config", scRoot), *newPath; 1195 memset((void*)&obj0, 0, sizeof(obj0));
1209 struct dirtree *new = dirtree_add_node(0, path, 0); 1196 ourSims->simsLua->lock(ourSims->simsLua);
1210 int i, j; 1197 while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true)
1198 {
1199 q0 = obj0.data;
1200 char *type = "unsorted";
1211 1201
1212 ourSims = xzalloc(sizeof(simList)); 1202 if (LUA_TTABLE == q0->type)
1213 ourSims->byTab = qtreetbl(0); 1203 {
1214 new->extra = (long) ourSims; 1204 panes = 4;
1215 dirtree_handle_callback(new, filterSims); 1205 q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1;
1206 q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f;
1207 q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s;
1208 if (0 == panes)
1209 {
1210 pane = 2;
1211 window = 0;
1212 type = Ttab;
1213 }
1214 else if (0 != pane)
1215 {
1216 pane = 0;
1217 window++;
1218 }
1219
1220 if (verb)
1221 V("%s sims of type %s, window %d, %d panes per window.", verb, type, window, panes);
1222 memset((void*)&obj1, 0, sizeof(obj1));
1223 q0->v.t->lock(q0->v.t);
1224 while(q0->v.t->getnext(q0->v.t, &obj1, false) == true)
1225 {
1226 q1 = obj1.data;
1227
1228 if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0))
1229 {
1230 simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false);
1231
1232 if (NULL == simd)
1233 {
1234 if (not)
1235 not(simd, q1->v.s, type, count, window, panes, pane);
1236 else
1237 E("Sim %s not found in ini list!", q1->v.s);
1238 }
1239 else
1240 {
1241 func(simd, q1->v.s, type, count, window, panes, pane);
1242 count++;
1243 pane++;
1244 if (pane >= panes)
1245 {
1246 pane = 0;
1247 window++;
1248 }
1249 }
1250 }
1251 }
1252 q0->v.t->unlock(q0->v.t);
1253 }
1254 }
1255 ourSims->simsLua->unlock(ourSims->simsLua);
1256}
1257
1258void simNotFound(simData *simd, char *sim, char *type, int count, int window, int panes, int pane)
1259{
1260 char *path = xmprintf("%s/%s.shini", scEtc, sim);
1261 qlisttbl_t *ini = qconfig_parse_file(NULL, path, '=');
1262
1263 if (NULL == ini)
1264 E("Can't find %s", path);
1265 else
1266 {
1267 simd = xzalloc(sizeof(simData));
1268 simd->tab = sim;
1269 simd->name = qstrunchar(ini->getstr(ini, "Region.RegionName", true), '"', '"');
1270 simd->UUID = qstrunchar(ini->getstr(ini, "Region.RegionUUID", true), '"', '"');
1271// simd->regionType = qstrunchar(ini->getstr(ini, "Region.RegionType", true), '"', '"');
1272 simd->sizeX = getIntFromIni(ini, "Region.SizeX");
1273 simd->sizeY = getIntFromIni(ini, "Region.SizeY");
1274 simd->sizeZ = getIntFromIni(ini, "Region.SizeZ");
1275// TODO - store a pointer instead of multiple copies of the data.
1276 ourSims->byTab->put(ourSims->byTab, sim, simd, sizeof(simData));
1277 if (strcmp("unsorted", type) == 0)
1278 ourSims->unsorted->put(ourSims->unsorted, sim, simd, sizeof(simData));
1279 ini->free(ini);
1280 free(simd);
1281 }
1216 free(path); 1282 free(path);
1283}
1217 1284
1218 char *file = xmprintf("%s/sims.lua", scEtc);
1219 char *tnm = "sims = -- Note these are .shini / tmux tab short names.\n{\n {['type'] = 'unsorted';\n";
1220 struct stat st;
1221 int s = stat(file, &st);
1222 int fd = -1;
1223 size_t l = strlen(tnm);
1224 1285
1225 ourSims->simsLua = Lua2tree(file, "sims"); 1286void freeSimList(simList *sims)
1226// dumpLuaTree(ourSims->simsLua, "simsLua", 0); 1287{
1288 int i;
1227 1289
1228 if (s) 1290 for (i = 0; i < sims->num; i++)
1291 free(sims->sims[i]);
1292 free(sims->sims);
1293
1294 qtreetbl_obj_t obj;
1295 memset((void*) &obj, 0, sizeof(obj)); // start from the minimum.
1296 sims->byTab->lock(sims->byTab);
1297 while (sims->byTab->getnext(sims->byTab, &obj, false) == true)
1229 { 1298 {
1230 I("Creating sims %s.", file); 1299 char *name = qmemdup(obj.name, obj.namesize); // keep the name
1231 fd = notstdio(xcreate_stdio(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR)); 1300 size_t namesize = obj.namesize; // for removal argument
1301 {
1302 simData *simd = (simData *) obj.data;
1303
1304 if (NULL != simd)
1305 {
1306 free(simd->name);
1307// free(simd->tab);
1308 free(simd->UUID);
1309// free(simd->regionType);
1310 free(simd->estate);
1311 free(simd->owner);
1312 free(simd->paneID);
1313 }
1314 }
1315// sims->byTab->remove_by_obj(sims->byTab, obj.name, obj.namesize); // remove
1316// obj = sims->byTab->find_nearest(sims->byTab, name, namesize, false); // rewind one step back
1317 free(name); // clean up
1232 } 1318 }
1319 sims->byTab->unlock(sims->byTab);
1320 sims->byTab->free(sims->byTab);
1321 freeLuaTree(sims->simsLua);
1322 freeLuaTree(sims->unsorted);
1323
1324 free(sims);
1325}
1326
1327// Get the details from all the .ini or .shini sim files.
1328// Creates the .shini and sims.lua files if it's an old install.
1329simList *getSims()
1330{
1331 if (NULL != ourSims) return ourSims;
1332
1333 int i, fd = -1;
1334 size_t l;
1335 char *file = xmprintf("%s/sims.lua", scEtc);
1336
1337 ourSims = xzalloc(sizeof(simList));
1338 ourSims->byTab = qtreetbl(0);
1339 ourSims->unsorted = qtreetbl(0);
1340 ourSims->doIt = FALSE;
1233 1341
1234 if (-1 != fd) 1342 // Read or create simsLua
1343 ourSims->simsLua = Lua2tree(file, "sims");
1344 if (NULL == ourSims->simsLua)
1235 { 1345 {
1236 if (l != writeall(fd, tnm, l)) 1346 ourSims->simsLua = qtreetbl(0);
1237 perror_msg("Writing %s", file); 1347 ourSims->doIt = TRUE;
1238 } 1348 }
1239 1349
1350 // Find all the old .ini files, convert them to .shini files if they don't exist.
1351 char *path = xmprintf("%s/config", scRoot), *newPath;
1352 struct dirtree *new = dirtree_add_node(0, path, 0);
1240 1353
1354 new->extra = (long) ourSims;
1355 dirtree_handle_callback(new, filterSims);
1356 free(path);
1241 for (i = 0; i < ourSims->num; i++) 1357 for (i = 0; i < ourSims->num; i++)
1242 { 1358 {
1243 char *sim = ourSims->sims[i], *name = xmprintf("%s/config/%s", scRoot, sim); 1359 char *sim = ourSims->sims[i], *name = xmprintf("%s/config/%s", scRoot, sim);
1244 qlisttbl_t *ini; 1360 qlisttbl_t *ini;
1245 simData *simd = xzalloc(sizeof(simData));
1246 struct dirtree *new = dirtree_add_node(0, name, 0); 1361 struct dirtree *new = dirtree_add_node(0, name, 0);
1247 1362
1248 free(name); 1363 free(name);
@@ -1253,20 +1368,10 @@ simList *getSims()
1253 { 1368 {
1254 path = xmprintf("%s/config/%s/%s.ini", scRoot, sim, name); 1369 path = xmprintf("%s/config/%s/%s.ini", scRoot, sim, name);
1255 newPath = xmprintf("%s/%s.shini", scEtc, name); 1370 newPath = xmprintf("%s/%s.shini", scEtc, name);
1256 d("Reading .ini file %s", path); 1371
1257 ini = qconfig_parse_file(NULL, path, '='); 1372 if (!qfile_exist(newPath))
1258 simd->name = qstrunchar(ini->getstr(ini, "Region.RegionName", true), '"', '"');
1259 simd->UUID = qstrunchar(ini->getstr(ini, "Region.RegionUUID", true), '"', '"');
1260 simd->regionType = qstrunchar(ini->getstr(ini, "Region.RegionType", true), '"', '"');
1261 simd->sizeX = getIntFromIni(ini, "Region.SizeX");
1262 simd->sizeY = getIntFromIni(ini, "Region.SizeY");
1263 simd->sizeZ = getIntFromIni(ini, "Region.SizeZ");
1264 simd->tab = name;
1265 ourSims->byTab->put(ourSims->byTab, name, simd, sizeof(simData));
1266
1267 if ((!qfile_exist(newPath)))
1268 { 1373 {
1269 char *cmd = xmprintf("sed -E" 1374 char *cmd = xmprintf("sed -E"
1270 " -e 's#\\[Const]#\\[Const] ; fakeVariableCozOpenSim='' ; pushd ../current/bin; ./sledjchisl $1 `basename $0`; popd ; exit 0#'" 1375 " -e 's#\\[Const]#\\[Const] ; fakeVariableCozOpenSim='' ; pushd ../current/bin; ./sledjchisl $1 `basename $0`; popd ; exit 0#'"
1271 " -e 's/mysim=\"[[:digit:]]*\"/mysim=\"%s\"/'" 1376 " -e 's/mysim=\"[[:digit:]]*\"/mysim=\"%s\"/'"
1272 " -e 's/sim\\$\\{Const\\|mysim\\}/\\$\\{Const\\|mysim\\}/g'" 1377 " -e 's/sim\\$\\{Const\\|mysim\\}/\\$\\{Const\\|mysim\\}/g'"
@@ -1275,100 +1380,206 @@ simList *getSims()
1275 " -e '/LogFile.*/d'" 1380 " -e '/LogFile.*/d'"
1276 " -e '/StatsLogFile.*/d'" 1381 " -e '/StatsLogFile.*/d'"
1277 " -e '/ConsoleHistoryFile.*/d'" 1382 " -e '/ConsoleHistoryFile.*/d'"
1278 " %s >%s", simd->tab, path, newPath); 1383 " %s >%s", name, path, newPath);
1279 1384
1280 I("Writing .shini file %s", newPath); 1385 V("Converting %s.ini -> %s", path, newPath);
1281 D(cmd); 1386 D(cmd);
1282 j = system(cmd); 1387 if (!WIFEXITED(system(cmd)))
1283 if (!WIFEXITED(j))
1284 E("sed command failed!"); 1388 E("sed command failed!");
1285 else 1389 else
1286 { 1390 {
1287 free(cmd); 1391 free(cmd);
1288 cmd = xmprintf("chmod ugo+x %s", newPath); 1392 cmd = xmprintf("chmod ugo+x %s", newPath);
1289 j = system(cmd); 1393 if (!WIFEXITED(system(cmd)))
1290 if (!WIFEXITED(j))
1291 E("chmod command failed!"); 1394 E("chmod command failed!");
1395 free(cmd);
1292 1396
1293 char *link = xmprintf("%s/%s.shini", scBin, simd->tab); 1397 char *link = xmprintf("%s/%s.shini", scBin, name);
1294 I("Symlinking %s to %s", newPath, link); 1398 I("Symlinking %s to %s", newPath, link);
1399 if (qfile_exist(link))
1400 {
1401 cmd = xmprintf("rm %s", link);
1402 if (!WIFEXITED(system(cmd)))
1403 E("rm command failed!");
1404 free(cmd);
1405 }
1295 if (0 != symlink(newPath, link)) 1406 if (0 != symlink(newPath, link))
1296 perror_msg("Symlinking %s to %s", newPath, link); 1407 perror_msg("Symlinking %s to %s", newPath, link);
1297 free(link); 1408 free(link);
1298 } 1409 }
1299 free(cmd);
1300 } 1410 }
1301 ini->free(ini);
1302 free(newPath); 1411 free(newPath);
1303 free(path); 1412 free(path);
1304 } 1413 }
1305 else 1414 free(name);
1306 free(name); 1415 }
1416// dumpLuaTree(ourSims->simsLua, "simsLua", 0);
1417// dumpLuaTree(ourSims->byTab, "byTab", 0);
1307 1418
1308 if (-1 != fd) 1419 // Read all the .shini files.
1420 forEachSim(NULL, NULL, simNotFound);
1421// dumpLuaTree(ourSims->simsLua, "simsLua", 0);
1422// dumpLuaTree(ourSims->byTab, "byTab", 0);
1423// dumpLuaTree(ourSims->unsorted, "unsorted", 0);
1424
1425 // Check for any .shini files not in sims.lua, add them to the unsorted list.
1426 for (i = 0; i < ourSims->num; i++)
1427 free(ourSims->sims[i]);
1428 ourSims->num = 0;
1429 new = dirtree_add_node(0, scEtc, 0);
1430 new->extra = (long) ourSims;
1431 dirtree_handle_callback(new, filterShinis);
1432 for (i = 0; i < ourSims->num; i++)
1433 {
1434 simData *simd = ourSims->byTab->get(ourSims->byTab, ourSims->sims[i], NULL, false);
1435 if (NULL == simd)
1309 { 1436 {
1310 tnm = xmprintf(" '%s', \n", simd->tab); 1437 V("Shini NOT found in list - %s/%s.shini", scEtc, ourSims->sims[i]);
1311 l = strlen(tnm); 1438 simNotFound(simd, ourSims->sims[i], "unsorted", 0, 0, 0, 0);
1312 if (l != writeall(fd, tnm, l)) 1439 ourSims->doIt = TRUE;
1313 perror_msg("Writing %s", file);
1314 free(tnm);
1315 } 1440 }
1316
1317 free(simd);
1318 } 1441 }
1442// dumpLuaTree(ourSims->simsLua, "simsLua", 0);
1443// dumpLuaTree(ourSims->byTab, "byTab", 0);
1444// dumpLuaTree(ourSims->unsorted, "unsorted", 0);
1319 1445
1320 if (-1 != fd) 1446 // Write the sims.lua_NEW file if needed.
1447 if (ourSims->doIt)
1321 { 1448 {
1322 tnm = " },\n}\nreturn sims\n"; 1449 char *tnm = xmprintf("mv -f %s/sims.lua %s/sims.lua.BACKUP", scEtc, scEtc);
1323 l = strlen(tnm);
1324 if (l != writeall(fd, tnm, l))
1325 perror_msg("Writing %s", file);
1326
1327 xclose(fd);
1328 }
1329 free(file);
1330
1331 return ourSims;
1332}
1333 1450
1334void freeSimList(simList *sims) 1451 if (!WIFEXITED(system(tnm)))
1335{ 1452 E("mv command failed!");
1336 int i; 1453 free(tnm);
1337 1454
1338 for (i = 0; i < sims->num; i++) 1455 free(file);
1339 free(sims->sims[i]); 1456 file = xmprintf("%s/sims.lua", scEtc);
1340 free(sims->sims); 1457 I("Creating sims %s.", file);
1341 1458
1342 qtreetbl_obj_t obj; 1459 fd = notstdio(xcreate_stdio(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR));
1343 memset((void*) &obj, 0, sizeof(obj)); // start from the minimum. 1460 if (-1 != fd)
1344 sims->byTab->lock(sims->byTab);
1345 while (sims->byTab->getnext(sims->byTab, &obj, false) == true)
1346 {
1347 char *name = qmemdup(obj.name, obj.namesize); // keep the name
1348 size_t namesize = obj.namesize; // for removal argument
1349 { 1461 {
1350 simData *simd = (simData *) obj.data; 1462 tnm = "sims = -- Note these are .shini / tmux tab short names.\n{\n";
1463 l = strlen(tnm);
1464 if (l != writeall(fd, tnm, l))
1465 perror_msg("Writing %s", file);
1351 1466
1352 if (NULL != simd) 1467 qtreetbl_obj_t obj0, obj1;
1468 qLua *q0, *q1;
1469
1470 memset((void*)&obj0, 0, sizeof(obj0));
1471 ourSims->simsLua->lock(ourSims->simsLua);
1472 while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true)
1353 { 1473 {
1354 free(simd->name); 1474 q0 = obj0.data;
1355 free(simd->tab); 1475 char *type = "unsorted";
1356 free(simd->UUID); 1476
1357 free(simd->regionType); 1477 if (LUA_TTABLE == q0->type)
1358 free(simd->estate); 1478 {
1359 free(simd->owner); 1479 tnm = " {";
1360 free(simd->paneID); 1480 l = strlen(tnm);
1481 if (l != writeall(fd, tnm, l))
1482 perror_msg("Writing %s", file);
1483 q1 = q0->v.t->get(q0->v.t, "type", NULL, false);
1484 if (NULL != q1)
1485 {
1486 type = q1->v.s;
1487 tnm = xmprintf("['type'] = '%s'; ", type);
1488 l = strlen(tnm);
1489 if (l != writeall(fd, tnm, l))
1490 perror_msg("Writing %s", file);
1491 free(tnm);
1492 }
1493 q1 = q0->v.t->get(q0->v.t, "number", NULL, false);
1494 if (NULL != q1)
1495 {
1496 tnm = xmprintf("['number'] = %d; ", (int) q1->v.f);
1497 l = strlen(tnm);
1498 if (l != writeall(fd, tnm, l))
1499 perror_msg("Writing %s", file);
1500 free(tnm);
1501 }
1502 q1 = q0->v.t->get(q0->v.t, "panes", NULL, false);
1503 if (NULL != q1)
1504 {
1505 tnm = xmprintf("['panes'] = %d; ", (int) q1->v.f);
1506 l = strlen(tnm);
1507 if (l != writeall(fd, tnm, l))
1508 perror_msg("Writing %s", file);
1509 free(tnm);
1510 }
1511
1512 if (strcmp("unsorted", type) != 0)
1513 {
1514 memset((void*)&obj1, 0, sizeof(obj1));
1515 q0->v.t->lock(q0->v.t);
1516 while(q0->v.t->getnext(q0->v.t, &obj1, false) == true)
1517 {
1518 q1 = obj1.data;
1519
1520 if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0))
1521 {
1522 tnm = xmprintf("\n '%s',", q1->v.s);
1523 l = strlen(tnm);
1524 if (l != writeall(fd, tnm, l))
1525 perror_msg("Writing %s", file);
1526 free(tnm);
1527 }
1528 }
1529 q0->v.t->unlock(q0->v.t);
1530 }
1531 else
1532 {
1533 memset((void*)&obj1, 0, sizeof(obj1));
1534 ourSims->unsorted->lock(ourSims->unsorted);
1535 while(ourSims->unsorted->getnext(ourSims->unsorted, &obj1, false) == true)
1536 {
1537 simData *simd = obj1.data;
1538
1539 if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0))
1540 {
1541 tnm = xmprintf("\n '%s',", simd->tab);
1542 l = strlen(tnm);
1543 if (l != writeall(fd, tnm, l))
1544 perror_msg("Writing %s", file);
1545 free(tnm);
1546 }
1547 }
1548 ourSims->unsorted->unlock(ourSims->unsorted);
1549 }
1550 }
1551 tnm = "\n },\n";
1552 l = strlen(tnm);
1553 if (l != writeall(fd, tnm, l))
1554 perror_msg("Writing %s", file);
1361 } 1555 }
1362 } 1556 ourSims->simsLua->unlock(ourSims->simsLua);
1363 sims->byTab->remove_by_obj(sims->byTab, obj.name, obj.namesize); // remove 1557 tnm = "}\nreturn sims\n";
1364 obj = sims->byTab->find_nearest(sims->byTab, name, namesize, false); // rewind one step back 1558 l = strlen(tnm);
1365 free(name); // clean up 1559 if (l != writeall(fd, tnm, l))
1560 perror_msg("Writing %s", file);
1561
1562 xclose(fd);
1563 }
1564 freeSimList(ourSims);
1565 free(file);
1566 // Reread everything.
1567 file = xmprintf("%s/sims.lua", scEtc);
1568 ourSims = xzalloc(sizeof(simList));
1569 ourSims->byTab = qtreetbl(0);
1570 ourSims->unsorted = qtreetbl(0);
1571 ourSims->doIt = FALSE;
1572 ourSims->simsLua = Lua2tree(file, "sims");
1573 forEachSim(NULL, NULL, simNotFound);
1574// dumpLuaTree(ourSims->simsLua, "simsLua", 0);
1575// dumpLuaTree(ourSims->byTab, "byTab", 0);
1576// dumpLuaTree(ourSims->unsorted, "unsorted", 0);
1366 } 1577 }
1367 sims->byTab->unlock(sims->byTab); 1578 free(file);
1368 sims->byTab->free(sims->byTab);
1369 freeLuaTree(sims->simsLua);
1370 1579
1371 free(sims); 1580// dumpLuaTree(ourSims->simsLua, "simsLua", 0);
1581// dumpLuaTree(ourSims->byTab, "byTab", 0);
1582 return ourSims;
1372} 1583}
1373 1584
1374// Expects either "simXX" or "ROBUST". 1585// Expects either "simXX" or "ROBUST".
@@ -1440,76 +1651,8 @@ int checkSimIsRunning(char *sim)
1440 return ret; 1651 return ret;
1441} 1652}
1442 1653
1443////////////////////////////////////////////////////////////////////////////////////////////////////
1444// Sim wrangling loop.
1445////////////////////////////////////////////////////////////////////////////////////////////////////
1446typedef void (*simFunction)(simData *simd, char *type, int count, int window, int panes, int pane);
1447void forEachSim(char *verb, simFunction func)
1448{
1449 qtreetbl_obj_t obj0, obj1;
1450 qLua *q0, *q1;
1451 int count = 0, window = 0, panes = 4, pane = 0;
1452
1453 ourSims->doWait = 1;
1454 memset((void*)&obj0, 0, sizeof(obj0));
1455 ourSims->simsLua->lock(ourSims->simsLua);
1456 while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true)
1457 {
1458 q0 = obj0.data;
1459 char *type = "unsorted";
1460
1461 if (LUA_TTABLE == q0->type)
1462 {
1463 panes = 4;
1464 q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1;
1465 q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f;
1466 q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s;
1467 if (0 == panes)
1468 {
1469 pane = 2;
1470 window = 0;
1471 type = Ttab;
1472 }
1473 else if (0 != pane)
1474 {
1475 pane = 0;
1476 window++;
1477 }
1478
1479 if (verb)
1480 V("%s sims of type %s, window %d, %d panes per window.", verb, type, window, panes);
1481 memset((void*)&obj1, 0, sizeof(obj1));
1482 q0->v.t->lock(q0->v.t);
1483 while(q0->v.t->getnext(q0->v.t, &obj1, false) == true)
1484 {
1485 q1 = obj1.data;
1486
1487 if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0))
1488 {
1489 simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false);
1490
1491 if (NULL == simd)
1492 E("Sim %s not found in ini list!", q1->v.s);
1493 else
1494 {
1495 func(simd, type, count, window, panes, pane);
1496 count++;
1497 pane++;
1498 if (pane >= panes)
1499 {
1500 pane = 0;
1501 window++;
1502 }
1503 }
1504 }
1505 }
1506 q0->v.t->unlock(q0->v.t);
1507 }
1508 }
1509 ourSims->simsLua->unlock(ourSims->simsLua);
1510}
1511 1654
1512void prepSims(simData *simd, char *type, int count, int window, int panes, int pane) 1655void prepSims(simData *simd, char *sim, char *type, int count, int window, int panes, int pane)
1513{ 1656{
1514 char *path = xmprintf("%s/%s.shini", scEtc, simd->tab); 1657 char *path = xmprintf("%s/%s.shini", scEtc, simd->tab);
1515 char *newPath = xmprintf("%s/sim%d/%s.ini", scTemp, count, simd->tab); // Coz OpenSim sucks. 1658 char *newPath = xmprintf("%s/sim%d/%s.ini", scTemp, count, simd->tab); // Coz OpenSim sucks.
@@ -1586,7 +1729,7 @@ void prepSims(simData *simd, char *type, int count, int window, int panes, int p
1586} 1729}
1587 1730
1588// Figure out where the sims are running. 1731// Figure out where the sims are running.
1589void findSimsTmux(simData *simd, char *type, int count, int window, int panes, int pane) 1732void findSimsTmux(simData *simd, char *sim, char *type, int count, int window, int panes, int pane)
1590{ 1733{
1591 simd->window = window; 1734 simd->window = window;
1592 simd->pane = pane; 1735 simd->pane = pane;
@@ -1597,7 +1740,7 @@ void findSimsTmux(simData *simd, char *type, int count, int window, int panes, i
1597 freeLuaTree(IDs); 1740 freeLuaTree(IDs);
1598} 1741}
1599 1742
1600void doSimsThing(simData *simd, char *type, int count, int window, int panes, int pane) 1743void doSimsThing(simData *simd, char *sim, char *type, int count, int window, int panes, int pane)
1601{ 1744{
1602 // Check if only doing a single sim. 1745 // Check if only doing a single sim.
1603 int cont = FALSE; 1746 int cont = FALSE;
@@ -1632,7 +1775,7 @@ void doSimsThing(simData *simd, char *type, int count, int window, int panes, in
1632 doTmuxCmd("select-pane -t %s:%s -T '%s'", Tconsole, simd->paneID, simd->tab); 1775 doTmuxCmd("select-pane -t %s:%s -T '%s'", Tconsole, simd->paneID, simd->tab);
1633 snprintf(toybuf, sizeof(toybuf), "mono OpenSim.exe -inidirectory=%s/sim%d", scTemp, count); 1776 snprintf(toybuf, sizeof(toybuf), "mono OpenSim.exe -inidirectory=%s/sim%d", scTemp, count);
1634 sendTmuxCmd(simd->paneID, toybuf); 1777 sendTmuxCmd(simd->paneID, toybuf);
1635 if (0 == ourSims->doWait) 1778 if (0 == ourSims->doIt)
1636 { 1779 {
1637 snprintf(toybuf, sizeof(toybuf), "INITIALIZATION COMPLETE FOR %s", simd->name); 1780 snprintf(toybuf, sizeof(toybuf), "INITIALIZATION COMPLETE FOR %s", simd->name);
1638 waitTmuxText(simd->paneID, toybuf); 1781 waitTmuxText(simd->paneID, toybuf);
@@ -1645,7 +1788,7 @@ void doSimsThing(simData *simd, char *type, int count, int window, int panes, in
1645 { 1788 {
1646// TODO - some compromise, do a premptive load check if we are not doing a wait anyway. 1789// TODO - some compromise, do a premptive load check if we are not doing a wait anyway.
1647 } 1790 }
1648 ourSims->doWait = ((count + 1) % bulkSims); 1791 ourSims->doIt = ((count + 1) % bulkSims);
1649 } 1792 }
1650 break; 1793 break;
1651 } 1794 }
@@ -1668,7 +1811,7 @@ void doSimsThing(simData *simd, char *type, int count, int window, int panes, in
1668 I("%s is being backed up to %s/backups/%s-%s.oar.", simd->name, scRoot, simd->tab, date); 1811 I("%s is being backed up to %s/backups/%s-%s.oar.", simd->name, scRoot, simd->tab, date);
1669 snprintf(toybuf, sizeof(toybuf), "save oar --all %s/backups/%s-%s.oar", scRoot, simd->tab, date); 1812 snprintf(toybuf, sizeof(toybuf), "save oar --all %s/backups/%s-%s.oar", scRoot, simd->tab, date);
1670 sendTmuxCmd(simd->paneID, toybuf); 1813 sendTmuxCmd(simd->paneID, toybuf);
1671// if (0 == doWait) 1814// if (0 == do)
1672 { 1815 {
1673 memset(toybuf, 0, sizeof(toybuf)); 1816 memset(toybuf, 0, sizeof(toybuf));
1674 snprintf(toybuf, sizeof(toybuf), "Finished writing out OAR for %s", simd->name); 1817 snprintf(toybuf, sizeof(toybuf), "Finished writing out OAR for %s", simd->name);
@@ -1728,7 +1871,7 @@ void doSimsThing(simData *simd, char *type, int count, int window, int panes, in
1728 } 1871 }
1729} 1872}
1730 1873
1731void stopSims(simData *simd, char *type, int count, int window, int panes, int pane) 1874void stopSims(simData *simd, char *sim, char *type, int count, int window, int panes, int pane)
1732{ 1875{
1733 // NOTE - these sleeps are guesses, seems to work on my super desktop during testing. 1876 // NOTE - these sleeps are guesses, seems to work on my super desktop during testing.
1734 while (checkSimIsRunning(simd->tab)) 1877 while (checkSimIsRunning(simd->tab))
@@ -7668,6 +7811,7 @@ jit library is loaded or the JIT compiler will not be activated.
7668 // TODO - See https://stackoverflow.com/questions/2693948/how-do-i-retrieve-the-number-of-processors-on-c-linux, there are more portable ways, this seems to be GNU specific. 7811 // TODO - See https://stackoverflow.com/questions/2693948/how-do-i-retrieve-the-number-of-processors-on-c-linux, there are more portable ways, this seems to be GNU specific.
7669 int cpus = (int) sysconf(_SC_NPROCESSORS_CONF), cpusOnline = (int) sysconf(_SC_NPROCESSORS_ONLN); 7812 int cpus = (int) sysconf(_SC_NPROCESSORS_CONF), cpusOnline = (int) sysconf(_SC_NPROCESSORS_ONLN);
7670 7813
7814 ourSims->doIt = 1;
7671 if (0 == bulkSims) 7815 if (0 == bulkSims)
7672 bulkSims = (cpusOnline / 3) - 1; 7816 bulkSims = (cpusOnline / 3) - 1;
7673 sysinfo(&info); 7817 sysinfo(&info);
@@ -7709,7 +7853,7 @@ V("ARGS - %d %d %i |%s| %s |%s|", toys.optc, toys.optflags, currentMode, toys.
7709 doTmuxCmd("select-pane -t 0 -T 'ROBUST'", Tcmd, scRun, Tsocket); 7853 doTmuxCmd("select-pane -t 0 -T 'ROBUST'", Tcmd, scRun, Tsocket);
7710 7854
7711 // Create all the tmux windows, panes, and temporary .ini files coz OpenSim sucketh. 7855 // Create all the tmux windows, panes, and temporary .ini files coz OpenSim sucketh.
7712 forEachSim("Prepping", prepSims); 7856 forEachSim("Prepping", prepSims, NULL);
7713 waitTmuxText(d, "INITIALIZATION COMPLETE FOR ROBUST"); 7857 waitTmuxText(d, "INITIALIZATION COMPLETE FOR ROBUST");
7714 I("ROBUST is done starting up."); 7858 I("ROBUST is done starting up.");
7715 free(d); 7859 free(d);
@@ -7721,15 +7865,16 @@ V("ARGS - %d %d %i |%s| %s |%s|", toys.optc, toys.optflags, currentMode, toys.
7721 goto finished; 7865 goto finished;
7722 } 7866 }
7723 else // Find out where the sims are in tmux. 7867 else // Find out where the sims are in tmux.
7724 forEachSim(NULL, findSimsTmux); 7868 forEachSim(NULL, findSimsTmux, NULL);
7725 7869
7726 // Do stuff with the sims. 7870 // Do stuff with the sims.
7727 forEachSim("Doing", doSimsThing); 7871 ourSims->doIt = 1;
7872 forEachSim("Doing", doSimsThing, NULL);
7728 7873
7729 if ((STOP == currentMode) && (NULL == ourSims->target)) 7874 if ((STOP == currentMode) && (NULL == ourSims->target))
7730 { 7875 {
7731 // Stop all the sims. 7876 // Stop all the sims.
7732 forEachSim(NULL, stopSims); 7877 forEachSim(NULL, stopSims, NULL);
7733 I("Closing all the other windows."); 7878 I("Closing all the other windows.");
7734 // First figure out what panes and windows are left. 7879 // First figure out what panes and windows are left.
7735 snprintf(toybuf, sizeof(toybuf), "echo 'IDs={' >%s/IDs_ALL.lua", scTemp); 7880 snprintf(toybuf, sizeof(toybuf), "echo 'IDs={' >%s/IDs_ALL.lua", scTemp);