diff options
Diffstat (limited to 'src/sledjchisl/sledjchisl.c')
-rw-r--r-- | src/sledjchisl/sledjchisl.c | 796 |
1 files changed, 325 insertions, 471 deletions
diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c index c068d57..12c03cd 100644 --- a/src/sledjchisl/sledjchisl.c +++ b/src/sledjchisl/sledjchisl.c | |||
@@ -1090,6 +1090,10 @@ struct _simList | |||
1090 | int len, num; | 1090 | int len, num; |
1091 | char **sims; | 1091 | char **sims; |
1092 | qtreetbl_t *byTab, *simsLua; | 1092 | qtreetbl_t *byTab, *simsLua; |
1093 | // Stuff for the looping through sims doing things and waiting. | ||
1094 | char *target; | ||
1095 | float la; | ||
1096 | int doWait; | ||
1093 | }; | 1097 | }; |
1094 | simList *ourSims = NULL; | 1098 | simList *ourSims = NULL; |
1095 | 1099 | ||
@@ -1435,6 +1439,305 @@ int checkSimIsRunning(char *sim) | |||
1435 | return ret; | 1439 | return ret; |
1436 | } | 1440 | } |
1437 | 1441 | ||
1442 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
1443 | // Sim wrangling loop. | ||
1444 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
1445 | typedef void (*simFunction)(simData *simd, char *type, int count, int window, int panes, int pane); | ||
1446 | void forEachSim(char *verb, simFunction func) | ||
1447 | { | ||
1448 | qtreetbl_obj_t obj0, obj1; | ||
1449 | qLua *q0, *q1; | ||
1450 | int count = 0, window = 0, panes = 4, pane = 0; | ||
1451 | |||
1452 | ourSims->doWait = 1; | ||
1453 | memset((void*)&obj0, 0, sizeof(obj0)); | ||
1454 | ourSims->simsLua->lock(ourSims->simsLua); | ||
1455 | while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true) | ||
1456 | { | ||
1457 | q0 = obj0.data; | ||
1458 | char *type = "unsorted"; | ||
1459 | |||
1460 | if (LUA_TTABLE == q0->type) | ||
1461 | { | ||
1462 | panes = 4; | ||
1463 | q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1; | ||
1464 | q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f; | ||
1465 | q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s; | ||
1466 | if (0 == panes) | ||
1467 | { | ||
1468 | pane = 2; | ||
1469 | window = 0; | ||
1470 | type = Ttab; | ||
1471 | } | ||
1472 | else if (0 != pane) | ||
1473 | { | ||
1474 | pane = 0; | ||
1475 | window++; | ||
1476 | } | ||
1477 | |||
1478 | if (verb) | ||
1479 | V("%s sims of type %s, window %d, %d panes per window.", verb, type, window, panes); | ||
1480 | memset((void*)&obj1, 0, sizeof(obj1)); | ||
1481 | q0->v.t->lock(q0->v.t); | ||
1482 | while(q0->v.t->getnext(q0->v.t, &obj1, false) == true) | ||
1483 | { | ||
1484 | q1 = obj1.data; | ||
1485 | |||
1486 | if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0)) | ||
1487 | { | ||
1488 | simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false); | ||
1489 | |||
1490 | if (NULL == simd) | ||
1491 | E("Sim %s not found in ini list!", q1->v.s); | ||
1492 | else | ||
1493 | { | ||
1494 | func(simd, type, count, window, panes, pane); | ||
1495 | count++; | ||
1496 | pane++; | ||
1497 | if (pane >= panes) | ||
1498 | { | ||
1499 | pane = 0; | ||
1500 | window++; | ||
1501 | } | ||
1502 | } | ||
1503 | } | ||
1504 | } | ||
1505 | q0->v.t->unlock(q0->v.t); | ||
1506 | } | ||
1507 | } | ||
1508 | ourSims->simsLua->unlock(ourSims->simsLua); | ||
1509 | } | ||
1510 | |||
1511 | void prepSims(simData *simd, char *type, int count, int window, int panes, int pane) | ||
1512 | { | ||
1513 | char *path = xmprintf("%s/%s.shini", scEtc, simd->tab); | ||
1514 | char *newPath = xmprintf("%s/sim%d/%s.ini", scTemp, count, simd->tab); // Coz OpenSim sucks. | ||
1515 | char *cmd; | ||
1516 | |||
1517 | simd->window = window; | ||
1518 | simd->pane = pane; | ||
1519 | |||
1520 | // Make sure all tmux windows and panes are startned. | ||
1521 | // The bash invocations are so that the PATH is properly propagated. | ||
1522 | if (0 == panes) | ||
1523 | doTmuxCmd("split-window -hp 50 -d -t '%s:0.1' bash", Tconsole); | ||
1524 | else if (0 == pane) | ||
1525 | { | ||
1526 | doTmuxCmd("new-window -dc '%s/current/bin' -n '%s' -t '%s:%d' bash", scRoot, type, Tconsole, window); | ||
1527 | if (2 <= panes) | ||
1528 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.0' bash", Tconsole, window); | ||
1529 | if (4 <= panes) | ||
1530 | { | ||
1531 | doTmuxCmd("split-window -vp 50 -d -t '%s:%d.1' bash", Tconsole, window); | ||
1532 | doTmuxCmd("split-window -vp 50 -d -t '%s:%d.0' bash", Tconsole, window); | ||
1533 | } | ||
1534 | if (8 <= panes) | ||
1535 | { | ||
1536 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.3' bash", Tconsole, window); | ||
1537 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.2' bash", Tconsole, window); | ||
1538 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.1' bash", Tconsole, window); | ||
1539 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.0' bash", Tconsole, window); | ||
1540 | } | ||
1541 | } | ||
1542 | |||
1543 | // Create the temporary .ini files. | ||
1544 | snprintf(toybuf, sizeof(toybuf), "echo 'IDs={' >%s/IDs_%d.lua", scTemp, window); | ||
1545 | system(toybuf); | ||
1546 | doTmuxCmd("list-panes -t %d -F \"['%d #{pane_index}'] = '#{window_id}.#{pane_id}',\" >> %s/IDs_%d.lua", window, window, scTemp, window); | ||
1547 | snprintf(toybuf, sizeof(toybuf), "echo '}\nreturn IDs' >>%s/IDs_%d.lua", scTemp, window); | ||
1548 | system(toybuf); | ||
1549 | |||
1550 | snprintf(toybuf, sizeof(toybuf), "%s/IDs_%d.lua", scTemp, window); | ||
1551 | qtreetbl_t *IDs = Lua2tree(toybuf, "IDs"); | ||
1552 | snprintf(toybuf, sizeof(toybuf), "%d %d", window, pane); | ||
1553 | simd->paneID = xmprintf("%s", qLuaGet(IDs, toybuf)->v.s); | ||
1554 | freeLuaTree(IDs); | ||
1555 | |||
1556 | simd->portH = 8004 + count * 2; | ||
1557 | simd->portU = 8005 + count * 2; | ||
1558 | cmd = xmprintf("rm -fr %s/sim%d; mkdir -p %s/sim%d; sed -E" | ||
1559 | " -e 's@\\[Region\\]@" | ||
1560 | " paneID = \"\\%s\"\\n" | ||
1561 | "\\[Startup\\]\\n" | ||
1562 | " PIDFile = \"\\$\\{Paths\\|CachePath\\}\\/\\$\\{Const\\|mysim\\}\\.pid\"\\n" | ||
1563 | " LogFile = \"\\$\\{Paths\\|LogPath\\}\\/OpenSim_\\$\\{Const\\|mysim\\}\\.log\"\\n" | ||
1564 | " StatsLogFile = \"\\$\\{Paths\\|LogPath\\}\\/OpenSimStats_\\$\\{Const\\|mysim\\}\\.log\"\\n" | ||
1565 | " ConsoleHistoryFile = \"\\$\\{Paths\\|LogPath\\}\\/OpenSimConsoleHistory_\\$\\{Const\\|mysim\\}\\.txt\"\\n" | ||
1566 | "\\n\\[Region\\]@'" | ||
1567 | " -e 's/InternalPort[[:space:]]*=[[:space:]]*[[:digit:]]+/InternalPort = %d/'" | ||
1568 | " -e 's/InternalPort[[:space:]]*=[[:space:]]*\"[[:digit:]]+\"/InternalPort = %d/'" | ||
1569 | " -e 's/http_listener_port[[:space:]]*=[[:space:]]*[[:digit:]]+/http_listener_port = %d/'" | ||
1570 | " -e 's/http_listener_port[[:space:]]*=[[:space:]]*\"[[:digit:]]+\"/http_listener_port = %d/'" | ||
1571 | " %s >%s", | ||
1572 | scTemp, count, | ||
1573 | scTemp, count, | ||
1574 | simd->paneID, | ||
1575 | simd->portU, | ||
1576 | simd->portU, | ||
1577 | simd->portH, | ||
1578 | simd->portH, | ||
1579 | path, newPath); | ||
1580 | D("Writing .ini file %s with ports %d %d", newPath, simd->portH, simd->portU); | ||
1581 | if (!WIFEXITED(system(cmd))) | ||
1582 | E("sed command failed!"); | ||
1583 | free(cmd); | ||
1584 | free(newPath); | ||
1585 | free(path); | ||
1586 | } | ||
1587 | |||
1588 | // Figure out where the sims are running. | ||
1589 | void findSimsTmux(simData *simd, char *type, int count, int window, int panes, int pane) | ||
1590 | { | ||
1591 | simd->window = window; | ||
1592 | simd->pane = pane; | ||
1593 | snprintf(toybuf, sizeof(toybuf), "%s/IDs_%d.lua", scTemp, window); | ||
1594 | qtreetbl_t *IDs = Lua2tree(toybuf, "IDs"); | ||
1595 | snprintf(toybuf, sizeof(toybuf), "%d %d", window, pane); | ||
1596 | simd->paneID = xmprintf("%s", qLuaGet(IDs, toybuf)->v.s); | ||
1597 | freeLuaTree(IDs); | ||
1598 | } | ||
1599 | |||
1600 | void doSimsThing(simData *simd, char *type, int count, int window, int panes, int pane) | ||
1601 | { | ||
1602 | // Check if only doing a single sim. | ||
1603 | int cont = FALSE; | ||
1604 | if (NULL != ourSims->target) | ||
1605 | { | ||
1606 | cont = TRUE; | ||
1607 | snprintf(toybuf, sizeof(toybuf), "%s.shini", simd->tab); | ||
1608 | if | ||
1609 | ( | ||
1610 | (strcmp(ourSims->target, simd->name) == 0) || | ||
1611 | (strcmp(ourSims->target, simd->tab) == 0) || | ||
1612 | (strcmp(ourSims->target, toybuf) == 0) | ||
1613 | ) | ||
1614 | cont = FALSE; | ||
1615 | snprintf(toybuf, sizeof(toybuf), "%s.ini", simd->tab); | ||
1616 | if (strcmp(ourSims->target, toybuf) == 0) | ||
1617 | cont = FALSE; | ||
1618 | snprintf(toybuf, sizeof(toybuf), "sim%d.ini", count); | ||
1619 | if (strcmp(ourSims->target, toybuf) == 0) | ||
1620 | cont = FALSE; | ||
1621 | if (cont) | ||
1622 | return; | ||
1623 | } | ||
1624 | |||
1625 | switch (currentMode) | ||
1626 | { | ||
1627 | case START : // "start sim01" "start 'Welcome sim'" "start Welcome.ini" "start Welcome" "start" start everything | ||
1628 | { | ||
1629 | if (!checkSimIsRunning(simd->tab)) | ||
1630 | { | ||
1631 | I("Tmux tab [%d:%s](pane %d) tmux ID %s, from %s/sim%d - %s is starting.", window, type, pane, simd->paneID, scTemp, count, simd->name); | ||
1632 | 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); | ||
1634 | sendTmuxCmd(simd->paneID, toybuf); | ||
1635 | if (0 == ourSims->doWait) | ||
1636 | { | ||
1637 | snprintf(toybuf, sizeof(toybuf), "INITIALIZATION COMPLETE FOR %s", simd->name); | ||
1638 | waitTmuxText(simd->paneID, toybuf); | ||
1639 | I("%s is done starting up.", simd->name); | ||
1640 | ourSims->la = waitLoadAverage(ourSims->la, loadAverageInc, simTimeOut); | ||
1641 | if (1 < bulkSims) | ||
1642 | bulkSims = bulkSims / 2; | ||
1643 | } | ||
1644 | else | ||
1645 | { | ||
1646 | // TODO - some compromise, do a premptive load check if we are not doing a wait anyway. | ||
1647 | } | ||
1648 | ourSims->doWait = ((count + 1) % bulkSims); | ||
1649 | } | ||
1650 | break; | ||
1651 | } | ||
1652 | |||
1653 | case BACKUP : // "backup 'onefang rejected'" "backup sim01" "backup 'Welcome Sim'" "backup" backup everything | ||
1654 | { // TODO - If it's not a sim code, and not a sim name, it's an account inventory. | ||
1655 | if (checkSimIsRunning(simd->tab)) | ||
1656 | { | ||
1657 | struct timeval tv; | ||
1658 | time_t curtime; | ||
1659 | char date[DATE_TIME_LEN]; | ||
1660 | |||
1661 | // TODO - should collect names of existing backups, both tmux / ini name and proper name. | ||
1662 | // Scan backups directory once before this for loop, add details to sims list. | ||
1663 | // strip off the last bit of file name (YYYY-mm-dd_HH:MM:SS.oar) to get the name | ||
1664 | // keep in mind some old files had munged names like "Tiffanie_s_Paradise-2021-06-23_05:11:38.oar" | ||
1665 | gettimeofday(&tv, NULL); | ||
1666 | curtime = tv.tv_sec; | ||
1667 | strftime(date, DATE_TIME_LEN, "%F_%T", localtime(&curtime)); | ||
1668 | 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); | ||
1670 | sendTmuxCmd(simd->paneID, toybuf); | ||
1671 | // if (0 == doWait) | ||
1672 | { | ||
1673 | memset(toybuf, 0, sizeof(toybuf)); | ||
1674 | snprintf(toybuf, sizeof(toybuf), "Finished writing out OAR for %s", simd->name); | ||
1675 | waitTmuxText(simd->paneID, toybuf); | ||
1676 | I("%s is done backing up.", simd->name); | ||
1677 | // TODO - should delete / gitAR the old ones now. | ||
1678 | // Have a config option for delete / gitAR. | ||
1679 | ourSims->la = waitLoadAverage(ourSims->la, loadAverageInc, simTimeOut); | ||
1680 | } | ||
1681 | } | ||
1682 | break; | ||
1683 | } | ||
1684 | |||
1685 | case CREATE : // "create name x,y size" | ||
1686 | { | ||
1687 | break; | ||
1688 | } | ||
1689 | |||
1690 | case GITAR : // "gitAR i name" "gitAR o name" | ||
1691 | { | ||
1692 | break; | ||
1693 | } | ||
1694 | |||
1695 | case STATUS : | ||
1696 | { | ||
1697 | break; | ||
1698 | } | ||
1699 | |||
1700 | case STOP : // "stop sim01" "stop 'Welcome Sim'" "stop" stop everything | ||
1701 | { | ||
1702 | if (checkSimIsRunning(simd->tab)) | ||
1703 | { | ||
1704 | // Leave empty panes as is. | ||
1705 | sendTmuxCmd(simd->paneID, "quit"); | ||
1706 | // There's three things that might happen - | ||
1707 | // Sim will quit, tmux pane will go away before we can see the shutdown message. | ||
1708 | // pane-exited hook might be useful here. | ||
1709 | // Sim will quit, tmux pane wont go away. Dunno yet if waitTmuxText() will still work. | ||
1710 | // pane-died hook might be useful here. | ||
1711 | // Sim fails to quit, error message on the pane that we want to read, wont see the shutdown message. | ||
1712 | // Also sim might not have finished starting up, and may even not be accepting comands yet. | ||
1713 | // TODO - cater for and test them all. | ||
1714 | // Could also loop on checkSimIsRunning(sim) | ||
1715 | // snprintf(toybuf, sizeof(toybuf), "[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); | ||
1716 | // waitTmuxText(nm, toybuf); | ||
1717 | // I("%s is done stopping.", simd->name); | ||
1718 | // la = waitLoadAverage(la, loadAverageInc, simTimeOut); | ||
1719 | } | ||
1720 | break; | ||
1721 | } | ||
1722 | |||
1723 | default : | ||
1724 | { | ||
1725 | E("Unknown command! %s", toys.optargs[0]); | ||
1726 | break; | ||
1727 | } | ||
1728 | } | ||
1729 | } | ||
1730 | |||
1731 | void stopSims(simData *simd, char *type, int count, int window, int panes, int pane) | ||
1732 | { | ||
1733 | // NOTE - these sleeps are guesses, seems to work on my super desktop during testing. | ||
1734 | while (checkSimIsRunning(simd->tab)) | ||
1735 | usleep(100000); | ||
1736 | usleep(10000); | ||
1737 | doTmuxCmd("kill-pane -t %s", simd->paneID); | ||
1738 | I("Tmux tab [%d:%s](pane %d) tmux ID %s, from %s/sim%d - %s has stopped.", window, type, pane, simd->paneID, scTemp, count, simd->name); | ||
1739 | } | ||
1740 | |||
1438 | 1741 | ||
1439 | static void PrintEnv(qgrow_t *reply, char *label, char **envp) | 1742 | static void PrintEnv(qgrow_t *reply, char *label, char **envp) |
1440 | { | 1743 | { |
@@ -7740,18 +8043,15 @@ fcgiDone: | |||
7740 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 8043 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
7741 | // Start of OpenSim wrangling section. | 8044 | // Start of OpenSim wrangling section. |
7742 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 8045 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
7743 | char *target = NULL; | ||
7744 | struct sysinfo info; | 8046 | struct sysinfo info; |
7745 | float la; | ||
7746 | // 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. | 8047 | // 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. |
7747 | int cpus = (int) sysconf(_SC_NPROCESSORS_CONF), cpusOnline = (int) sysconf(_SC_NPROCESSORS_ONLN); | 8048 | int cpus = (int) sysconf(_SC_NPROCESSORS_CONF), cpusOnline = (int) sysconf(_SC_NPROCESSORS_ONLN); |
7748 | int doWait = 1; | ||
7749 | 8049 | ||
7750 | if (0 == bulkSims) | 8050 | if (0 == bulkSims) |
7751 | bulkSims = (cpusOnline / 3) - 1; | 8051 | bulkSims = (cpusOnline / 3) - 1; |
7752 | I("There are %i CPUs, %i of them are online. Doing %i sims at once.", cpus, cpusOnline, bulkSims); | ||
7753 | sysinfo(&info); | 8052 | sysinfo(&info); |
7754 | la = info.loads[0]/65536.0; | 8053 | ourSims->la = info.loads[0]/65536.0; |
8054 | I("There are %i CPUs, %i of them are online. Doing %i sims at once. LoadAverage = %f", cpus, cpusOnline, bulkSims, ourSims->la); | ||
7755 | 8055 | ||
7756 | if (0 == toys.optc) | 8056 | if (0 == toys.optc) |
7757 | ; | 8057 | ; |
@@ -7768,19 +8068,12 @@ fcgiDone: | |||
7768 | else if (strcmp(toys.optargs[0], "stop") == 0) | 8068 | else if (strcmp(toys.optargs[0], "stop") == 0) |
7769 | currentMode = STOP; | 8069 | currentMode = STOP; |
7770 | else | 8070 | else |
7771 | target = toys.optargs[0]; | 8071 | ourSims->target = toys.optargs[0]; |
7772 | if (2 == toys.optc) | 8072 | if (2 == toys.optc) |
7773 | target = toys.optargs[1]; | 8073 | ourSims->target = toys.optargs[1]; |
7774 | 8074 | V("ARGS - %d %d %i |%s| %s |%s|", toys.optc, toys.optflags, currentMode, toys.optargs[0], toys.optargs[1], ourSims->target); | |
7775 | //T("ARGS - %i |%s| |%s|", currentMode, toys.optargs[0], target); | ||
7776 | 8075 | ||
7777 | qtreetbl_obj_t obj0, obj1; | 8076 | // Start ROBUST or join the tmux session, or just figure out where the sims are running in tmux. |
7778 | qLua *q0, *q1; | ||
7779 | int count = 0, window = 0, panes = 4, pane = 0; | ||
7780 | |||
7781 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
7782 | // Start ROBUST or join the tmux session. | ||
7783 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
7784 | if ((START == currentMode) && !checkSimIsRunning("ROBUST")) | 8077 | if ((START == currentMode) && !checkSimIsRunning("ROBUST")) |
7785 | { | 8078 | { |
7786 | char *d = xmprintf("%s.{right}", Ttab); | 8079 | char *d = xmprintf("%s.{right}", Ttab); |
@@ -7794,136 +8087,8 @@ fcgiDone: | |||
7794 | free(c); | 8087 | free(c); |
7795 | doTmuxCmd("select-pane -t 0 -T 'ROBUST'", Tcmd, scRun, Tsocket); | 8088 | doTmuxCmd("select-pane -t 0 -T 'ROBUST'", Tcmd, scRun, Tsocket); |
7796 | 8089 | ||
7797 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 8090 | // Create all the tmux windows, panes, and temporary .ini files coz OpenSim sucketh. |
7798 | // Create all the tmux windows, panes, and temporary .ini files, coz OpenSim sucketh. | 8091 | forEachSim("Prepping", prepSims); |
7799 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
7800 | memset((void*)&obj0, 0, sizeof(obj0)); | ||
7801 | ourSims->simsLua->lock(ourSims->simsLua); | ||
7802 | while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true) | ||
7803 | { | ||
7804 | q0 = obj0.data; | ||
7805 | char *type = "unsorted"; | ||
7806 | |||
7807 | if (LUA_TTABLE == q0->type) | ||
7808 | { | ||
7809 | panes = 4; | ||
7810 | q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1; | ||
7811 | q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f; | ||
7812 | q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s; | ||
7813 | if (0 == panes) | ||
7814 | { | ||
7815 | pane = 2; | ||
7816 | window = 0; | ||
7817 | type = Ttab; | ||
7818 | } | ||
7819 | else if (0 != pane) | ||
7820 | { | ||
7821 | pane = 0; | ||
7822 | window++; | ||
7823 | } | ||
7824 | |||
7825 | V("Prepping sims of type %s, window %d, %d panes per window.", type, window, panes); | ||
7826 | |||
7827 | memset((void*)&obj1, 0, sizeof(obj1)); | ||
7828 | q0->v.t->lock(q0->v.t); | ||
7829 | while(q0->v.t->getnext(q0->v.t, &obj1, false) == true) | ||
7830 | { | ||
7831 | q1 = obj1.data; | ||
7832 | |||
7833 | if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0)) | ||
7834 | { | ||
7835 | simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false); | ||
7836 | |||
7837 | if (NULL == simd) | ||
7838 | E("Sim %s not found in ini list!", q1->v.s); | ||
7839 | else | ||
7840 | { | ||
7841 | char *path = xmprintf("%s/%s.shini", scEtc, simd->tab); | ||
7842 | char *newPath = xmprintf("%s/sim%d/%s.ini", scTemp, count, simd->tab); // Coz OpenSim. | ||
7843 | char *cmd; | ||
7844 | |||
7845 | simd->window = window; | ||
7846 | simd->pane = pane; | ||
7847 | |||
7848 | // The bash invocations are so that the PATH is properly propagated. | ||
7849 | if (0 == panes) | ||
7850 | doTmuxCmd("split-window -hp 50 -d -t '%s:0.1' bash", Tconsole); | ||
7851 | else if (0 == pane) | ||
7852 | { | ||
7853 | doTmuxCmd("new-window -dc '%s/current/bin' -n '%s' -t '%s:%d' bash", scRoot, type, Tconsole, window); | ||
7854 | if (2 <= panes) | ||
7855 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.0' bash", Tconsole, window); | ||
7856 | if (4 <= panes) | ||
7857 | { | ||
7858 | doTmuxCmd("split-window -vp 50 -d -t '%s:%d.1' bash", Tconsole, window); | ||
7859 | doTmuxCmd("split-window -vp 50 -d -t '%s:%d.0' bash", Tconsole, window); | ||
7860 | } | ||
7861 | if (8 <= panes) | ||
7862 | { | ||
7863 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.3' bash", Tconsole, window); | ||
7864 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.2' bash", Tconsole, window); | ||
7865 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.1' bash", Tconsole, window); | ||
7866 | doTmuxCmd("split-window -hp 50 -d -t '%s:%d.0' bash", Tconsole, window); | ||
7867 | } | ||
7868 | } | ||
7869 | snprintf(toybuf, sizeof(toybuf), "echo 'IDs={' >%s/IDs_%d.lua", scTemp, window); | ||
7870 | system(toybuf); | ||
7871 | doTmuxCmd("list-panes -t %d -F \"['%d #{pane_index}'] = '#{window_id}.#{pane_id}',\" >> %s/IDs_%d.lua", window, window, scTemp, window); | ||
7872 | snprintf(toybuf, sizeof(toybuf), "echo '}\nreturn IDs' >>%s/IDs_%d.lua", scTemp, window); | ||
7873 | system(toybuf); | ||
7874 | |||
7875 | snprintf(toybuf, sizeof(toybuf), "%s/IDs_%d.lua", scTemp, window); | ||
7876 | qtreetbl_t *IDs = Lua2tree(toybuf, "IDs"); | ||
7877 | snprintf(toybuf, sizeof(toybuf), "%d %d", window, pane); | ||
7878 | simd->paneID = xmprintf("%s", qLuaGet(IDs, toybuf)->v.s); | ||
7879 | freeLuaTree(IDs); | ||
7880 | |||
7881 | simd->portH = 8004 + count * 2; | ||
7882 | simd->portU = 8005 + count * 2; | ||
7883 | cmd = xmprintf("rm -fr %s/sim%d; mkdir -p %s/sim%d; sed -E" | ||
7884 | " -e 's@\\[Region\\]@" | ||
7885 | " paneID = \"\\%s\"\\n" | ||
7886 | "\\[Startup\\]\\n" | ||
7887 | " PIDFile = \"\\$\\{Paths\\|CachePath\\}\\/\\$\\{Const\\|mysim\\}\\.pid\"\\n" | ||
7888 | " LogFile = \"\\$\\{Paths\\|LogPath\\}\\/OpenSim_\\$\\{Const\\|mysim\\}\\.log\"\\n" | ||
7889 | " StatsLogFile = \"\\$\\{Paths\\|LogPath\\}\\/OpenSimStats_\\$\\{Const\\|mysim\\}\\.log\"\\n" | ||
7890 | " ConsoleHistoryFile = \"\\$\\{Paths\\|LogPath\\}\\/OpenSimConsoleHistory_\\$\\{Const\\|mysim\\}\\.txt\"\\n" | ||
7891 | "\\n\\[Region\\]@'" | ||
7892 | " -e 's/InternalPort[[:space:]]*=[[:space:]]*[[:digit:]]+/InternalPort = %d/'" | ||
7893 | " -e 's/InternalPort[[:space:]]*=[[:space:]]*\"[[:digit:]]+\"/InternalPort = %d/'" | ||
7894 | " -e 's/http_listener_port[[:space:]]*=[[:space:]]*[[:digit:]]+/http_listener_port = %d/'" | ||
7895 | " -e 's/http_listener_port[[:space:]]*=[[:space:]]*\"[[:digit:]]+\"/http_listener_port = %d/'" | ||
7896 | " %s >%s", | ||
7897 | scTemp, count, | ||
7898 | scTemp, count, | ||
7899 | simd->paneID, | ||
7900 | simd->portU, | ||
7901 | simd->portU, | ||
7902 | simd->portH, | ||
7903 | simd->portH, | ||
7904 | path, newPath); | ||
7905 | D("Writing .ini file %s with ports %d %d", newPath, simd->portH, simd->portU); | ||
7906 | int j = system(cmd); | ||
7907 | if (!WIFEXITED(j)) | ||
7908 | E("sed command failed!"); | ||
7909 | free(cmd); | ||
7910 | free(newPath); | ||
7911 | free(path); | ||
7912 | count++; | ||
7913 | pane++; | ||
7914 | if (pane >= panes) | ||
7915 | { | ||
7916 | pane = 0; | ||
7917 | window++; | ||
7918 | } | ||
7919 | } | ||
7920 | } | ||
7921 | } | ||
7922 | q0->v.t->unlock(q0->v.t); | ||
7923 | } | ||
7924 | } | ||
7925 | ourSims->simsLua->unlock(ourSims->simsLua); | ||
7926 | |||
7927 | waitTmuxText(d, "INITIALIZATION COMPLETE FOR ROBUST"); | 8092 | waitTmuxText(d, "INITIALIZATION COMPLETE FOR ROBUST"); |
7928 | I("ROBUST is done starting up."); | 8093 | I("ROBUST is done starting up."); |
7929 | free(d); | 8094 | free(d); |
@@ -7934,269 +8099,17 @@ fcgiDone: | |||
7934 | doTmuxCmd("select-window -t '%s' \\; attach-session -t '%s'", Tconsole, Tconsole); | 8099 | doTmuxCmd("select-window -t '%s' \\; attach-session -t '%s'", Tconsole, Tconsole); |
7935 | goto finished; | 8100 | goto finished; |
7936 | } | 8101 | } |
7937 | else | 8102 | else // Find out where the sims are in tmux. |
7938 | { | 8103 | forEachSim(NULL, findSimsTmux); |
7939 | // Find out where the sims are in tmux. | ||
7940 | memset((void*)&obj0, 0, sizeof(obj0)); | ||
7941 | ourSims->simsLua->lock(ourSims->simsLua); | ||
7942 | while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true) | ||
7943 | { | ||
7944 | q0 = obj0.data; | ||
7945 | char *type = "unsorted"; | ||
7946 | |||
7947 | if (LUA_TTABLE == q0->type) | ||
7948 | { | ||
7949 | panes = 4; | ||
7950 | q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1; | ||
7951 | q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f; | ||
7952 | q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s; | ||
7953 | if (0 == panes) | ||
7954 | { | ||
7955 | pane = 2; | ||
7956 | window = 0; | ||
7957 | type = Ttab; | ||
7958 | } | ||
7959 | else if (0 != pane) | ||
7960 | { | ||
7961 | pane = 0; | ||
7962 | window++; | ||
7963 | } | ||
7964 | |||
7965 | memset((void*)&obj1, 0, sizeof(obj1)); | ||
7966 | q0->v.t->lock(q0->v.t); | ||
7967 | while(q0->v.t->getnext(q0->v.t, &obj1, false) == true) | ||
7968 | { | ||
7969 | q1 = obj1.data; | ||
7970 | |||
7971 | if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0)) | ||
7972 | { | ||
7973 | simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false); | ||
7974 | |||
7975 | if (NULL == simd) | ||
7976 | E("Sim %s not found in ini list!", q1->v.s); | ||
7977 | else | ||
7978 | { | ||
7979 | simd->window = window; | ||
7980 | simd->pane = pane; | ||
7981 | |||
7982 | char *newPath = xmprintf("%s/sim%d/%s.ini", scTemp, count, simd->tab); // Coz OpenSim. | ||
7983 | |||
7984 | snprintf(toybuf, sizeof(toybuf), "%s/IDs_%d.lua", scTemp, window); | ||
7985 | qtreetbl_t *IDs = Lua2tree(toybuf, "IDs"); | ||
7986 | snprintf(toybuf, sizeof(toybuf), "%d %d", window, pane); | ||
7987 | simd->paneID = xmprintf("%s", qLuaGet(IDs, toybuf)->v.s); | ||
7988 | freeLuaTree(IDs); | ||
7989 | free(newPath); | ||
7990 | count++; | ||
7991 | pane++; | ||
7992 | if (pane >= panes) | ||
7993 | { | ||
7994 | pane = 0; | ||
7995 | window++; | ||
7996 | } | ||
7997 | } | ||
7998 | } | ||
7999 | } | ||
8000 | q0->v.t->unlock(q0->v.t); | ||
8001 | } | ||
8002 | } | ||
8003 | ourSims->simsLua->unlock(ourSims->simsLua); | ||
8004 | } | ||
8005 | |||
8006 | |||
8007 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
8008 | // Sim wrangling loop. | ||
8009 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
8010 | count = 0; window = 0; panes = 4; pane = 0; | ||
8011 | memset((void*)&obj0, 0, sizeof(obj0)); | ||
8012 | ourSims->simsLua->lock(ourSims->simsLua); | ||
8013 | while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true) | ||
8014 | { | ||
8015 | q0 = obj0.data; | ||
8016 | char *type = "unsorted"; | ||
8017 | |||
8018 | if (LUA_TTABLE == q0->type) | ||
8019 | { | ||
8020 | panes = 4; | ||
8021 | q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1; | ||
8022 | q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f; | ||
8023 | q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s; | ||
8024 | if (0 == panes) | ||
8025 | { | ||
8026 | pane = 2; | ||
8027 | window = 0; | ||
8028 | type = Ttab; | ||
8029 | } | ||
8030 | else if (0 != pane) | ||
8031 | { | ||
8032 | pane = 0; | ||
8033 | window++; | ||
8034 | } | ||
8035 | |||
8036 | V("Doing sims of type %s, window %d, %d panes per window.", type, window, panes); | ||
8037 | memset((void*)&obj1, 0, sizeof(obj1)); | ||
8038 | q0->v.t->lock(q0->v.t); | ||
8039 | while(q0->v.t->getnext(q0->v.t, &obj1, false) == true) | ||
8040 | { | ||
8041 | q1 = obj1.data; | ||
8042 | |||
8043 | if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0)) | ||
8044 | { | ||
8045 | simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false); | ||
8046 | |||
8047 | if (NULL == simd) | ||
8048 | E("Sim %s not found in ini list!", 5); | ||
8049 | else | ||
8050 | { | ||
8051 | // Check if only doing a single sim. | ||
8052 | int cont = FALSE; | ||
8053 | if (NULL != target) | ||
8054 | { | ||
8055 | cont = TRUE; | ||
8056 | snprintf(toybuf, sizeof(toybuf), "%s.shini", simd->tab); | ||
8057 | if | ||
8058 | ( | ||
8059 | (strcmp(target, q1->v.s) == 0) || | ||
8060 | (strcmp(target, simd->name) == 0) || | ||
8061 | (strcmp(target, simd->tab) == 0) || | ||
8062 | (strcmp(target, toybuf) == 0) | ||
8063 | ) | ||
8064 | cont = FALSE; | ||
8065 | snprintf(toybuf, sizeof(toybuf), "%s.ini", simd->tab); | ||
8066 | if (strcmp(target, toybuf) == 0) | ||
8067 | cont = FALSE; | ||
8068 | snprintf(toybuf, sizeof(toybuf), "sim%d.ini", count); | ||
8069 | if (strcmp(target, toybuf) == 0) | ||
8070 | cont = FALSE; | ||
8071 | } | ||
8072 | if (!cont) | ||
8073 | { | ||
8074 | switch (currentMode) | ||
8075 | { | ||
8076 | case START : // "start sim01" "start 'Welcome sim'" "start Welcome.ini" "start Welcome" "start" start everything | ||
8077 | { | ||
8078 | if (!checkSimIsRunning(simd->tab)) | ||
8079 | { | ||
8080 | I("Tmux tab [%d:%s](pane %d) tmux ID %s, from %s/sim%d - %s is starting.", window, type, pane, simd->paneID, scTemp, count, simd->name); | ||
8081 | doTmuxCmd("select-pane -t %s:%s -T '%s'", Tconsole, simd->paneID, simd->tab); | ||
8082 | snprintf(toybuf, sizeof(toybuf), "mono OpenSim.exe -inidirectory=%s/sim%d", scTemp, count); | ||
8083 | sendTmuxCmd(simd->paneID, toybuf); | ||
8084 | // TODO - some compromise, do a premptive load check if we are not doing a wait anyway. | ||
8085 | if (0 == doWait) | ||
8086 | { | ||
8087 | // doTmuxCmd("select-window -t %s:%d", Tconsole, simd->window); | ||
8088 | snprintf(toybuf, sizeof(toybuf), "INITIALIZATION COMPLETE FOR %s", simd->name); | ||
8089 | waitTmuxText(simd->paneID, toybuf); | ||
8090 | I("%s is done starting up.", simd->name); | ||
8091 | la = waitLoadAverage(la, loadAverageInc, simTimeOut); | ||
8092 | if (1 < bulkSims) | ||
8093 | bulkSims = bulkSims / 2; | ||
8094 | } | ||
8095 | doWait = ((count + 1) % bulkSims); | ||
8096 | } | ||
8097 | break; | ||
8098 | } | ||
8099 | |||
8100 | case BACKUP : // "backup 'onefang rejected'" "backup sim01" "backup 'Welcome Sim'" "backup" backup everything | ||
8101 | { // TODO - If it's not a sim code, and not a sim name, it's an account inventory. | ||
8102 | if (checkSimIsRunning(simd->tab)) | ||
8103 | { | ||
8104 | struct timeval tv; | ||
8105 | time_t curtime; | ||
8106 | char date[DATE_TIME_LEN]; | ||
8107 | |||
8108 | // TODO - should collect names of existing backups, both tmux / ini name and proper name. | ||
8109 | // Scan backups directory once before this for loop, add details to sims list. | ||
8110 | // strip off the last bit of file name (YYYY-mm-dd_HH:MM:SS.oar) to get the name | ||
8111 | // keep in mind some old files had munged names like "Tiffanie_s_Paradise-2021-06-23_05:11:38.oar" | ||
8112 | gettimeofday(&tv, NULL); | ||
8113 | curtime = tv.tv_sec; | ||
8114 | strftime(date, DATE_TIME_LEN, "%F_%T", localtime(&curtime)); | ||
8115 | I("%s is being backed up to %s/backups/%s-%s.oar.", simd->name, scRoot, simd->tab, date); | ||
8116 | snprintf(toybuf, sizeof(toybuf), "save oar --all %s/backups/%s-%s.oar", scRoot, simd->tab, date); | ||
8117 | sendTmuxCmd(simd->paneID, toybuf); | ||
8118 | // if (0 == doWait) | ||
8119 | { | ||
8120 | memset(toybuf, 0, sizeof(toybuf)); | ||
8121 | snprintf(toybuf, sizeof(toybuf), "Finished writing out OAR for %s", simd->name); | ||
8122 | waitTmuxText(cmd, toybuf); | ||
8123 | I("%s is done backing up.", simd->name); | ||
8124 | // TODO - should delete / gitAR the old ones now. | ||
8125 | // Have a config option for delete / gitAR. | ||
8126 | la = waitLoadAverage(la, loadAverageInc, simTimeOut); | ||
8127 | } | ||
8128 | } | ||
8129 | break; | ||
8130 | } | ||
8131 | |||
8132 | case CREATE : // "create name x,y size" | ||
8133 | { | ||
8134 | break; | ||
8135 | } | ||
8136 | |||
8137 | case GITAR : // "gitAR i name" "gitAR o name" | ||
8138 | { | ||
8139 | break; | ||
8140 | } | ||
8141 | |||
8142 | case STATUS : | ||
8143 | { | ||
8144 | break; | ||
8145 | } | ||
8146 | |||
8147 | case STOP : // "stop sim01" "stop 'Welcome Sim'" "stop" stop everything | ||
8148 | { | ||
8149 | if (checkSimIsRunning(simd->tab)) | ||
8150 | { | ||
8151 | // Leave empty panes as is. | ||
8152 | sendTmuxCmd(simd->paneID, "quit"); | ||
8153 | // There's three things that might happen - | ||
8154 | // Sim will quit, tmux pane will go away before we can see the shutdown message. | ||
8155 | // pane-exited hook might be useful here. | ||
8156 | // Sim will quit, tmux pane wont go away. Dunno yet if waitTmuxText() will still work. | ||
8157 | // pane-died hook might be useful here. | ||
8158 | // Sim fails to quit, error message on the pane that we want to read, wont see the shutdown message. | ||
8159 | // Also sim might not have finished starting up, and may even not be accepting comands yet. | ||
8160 | // TODO - cater for and test them all. | ||
8161 | // Could also loop on checkSimIsRunning(sim) | ||
8162 | // snprintf(toybuf, sizeof(toybuf), "[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); | ||
8163 | // waitTmuxText(nm, toybuf); | ||
8164 | // I("%s is done stopping.", simd->name); | ||
8165 | // la = waitLoadAverage(la, loadAverageInc, simTimeOut); | ||
8166 | } | ||
8167 | break; | ||
8168 | } | ||
8169 | |||
8170 | default : | ||
8171 | { | ||
8172 | E("Unknown command! %s", toys.optargs[0]); | ||
8173 | break; | ||
8174 | } | ||
8175 | } | ||
8176 | } | ||
8177 | |||
8178 | } | ||
8179 | |||
8180 | count++; | ||
8181 | pane++; | ||
8182 | if (pane >= panes) | ||
8183 | { | ||
8184 | pane = 0; | ||
8185 | window++; | ||
8186 | } | ||
8187 | } | ||
8188 | } | ||
8189 | q0->v.t->unlock(q0->v.t); | ||
8190 | } | ||
8191 | } | ||
8192 | ourSims->simsLua->unlock(ourSims->simsLua); | ||
8193 | 8104 | ||
8105 | // Do stuff with the sims. | ||
8106 | forEachSim("Doing", doSimsThing); | ||
8194 | 8107 | ||
8195 | if (START == currentMode) | 8108 | if (START == currentMode) |
8196 | { | 8109 | { |
8197 | if (checkSimIsRunning("ROBUST") && (NULL == target)) | 8110 | if (checkSimIsRunning("ROBUST") && (NULL == ourSims->target)) |
8198 | { | 8111 | { |
8199 | // Start up the web stuff. TODO - remove this once we handle the fcgi stuff ourselves. | 8112 | // TODO - remove this once we handle the fcgi stuff ourselves. |
8200 | I("Starting the web stuff."); | 8113 | I("Starting the web stuff."); |
8201 | char *c = xmprintf("spawn-fcgi -n -u %s -s %s/sledjchisl.socket -M 0660 -G www-data -- " | 8114 | char *c = xmprintf("spawn-fcgi -n -u %s -s %s/sledjchisl.socket -M 0660 -G www-data -- " |
8202 | "/usr/bin/valgrind --leak-check=full sledjchisl", | 8115 | "/usr/bin/valgrind --leak-check=full sledjchisl", |
@@ -8207,85 +8120,27 @@ fcgiDone: | |||
8207 | else | 8120 | else |
8208 | I("NOT Starting the web stuff."); | 8121 | I("NOT Starting the web stuff."); |
8209 | } | 8122 | } |
8210 | else if ((STOP == currentMode) && (NULL == target)) | 8123 | else if ((STOP == currentMode) && (NULL == ourSims->target)) |
8211 | { | 8124 | { |
8212 | memset((void*)&obj0, 0, sizeof(obj0)); | 8125 | // Stop all the sims. |
8213 | ourSims->simsLua->lock(ourSims->simsLua); | 8126 | forEachSim(NULL, stopSims); |
8214 | while(ourSims->simsLua->getnext(ourSims->simsLua, &obj0, false) == true) | 8127 | I("Closing all the other windows."); |
8215 | { | 8128 | // First figure out what panes and windows are left. |
8216 | q0 = obj0.data; | ||
8217 | char *type = "unsorted"; | ||
8218 | |||
8219 | if (LUA_TTABLE == q0->type) | ||
8220 | { | ||
8221 | panes = 4; | ||
8222 | q1 = q0->v.t->get(q0->v.t, "number", NULL, false); if (NULL != q1) window = q1->v.f - 1; | ||
8223 | q1 = q0->v.t->get(q0->v.t, "panes", NULL, false); if (NULL != q1) panes = q1->v.f; | ||
8224 | q1 = q0->v.t->get(q0->v.t, "type", NULL, false); if (NULL != q1) type = q1->v.s; | ||
8225 | if (0 == panes) | ||
8226 | { | ||
8227 | pane = 2; | ||
8228 | window = 0; | ||
8229 | type = Ttab; | ||
8230 | } | ||
8231 | else if (0 != pane) | ||
8232 | { | ||
8233 | pane = 0; | ||
8234 | window++; | ||
8235 | } | ||
8236 | |||
8237 | memset((void*)&obj1, 0, sizeof(obj1)); | ||
8238 | q0->v.t->lock(q0->v.t); | ||
8239 | while(q0->v.t->getnext(q0->v.t, &obj1, false) == true) | ||
8240 | { | ||
8241 | q1 = obj1.data; | ||
8242 | |||
8243 | if ((strcmp("number", obj1.name) != 0) && (strcmp("panes", obj1.name) != 0) && (strcmp("type", obj1.name) != 0)) | ||
8244 | { | ||
8245 | simData *simd = ourSims->byTab->get(ourSims->byTab, q1->v.s, NULL, false); | ||
8246 | |||
8247 | if (NULL == simd) | ||
8248 | E("Sim %s not found in ini list!", q1->v.s); | ||
8249 | else | ||
8250 | { | ||
8251 | // NOTE - these sleeps are guesses, seems to work on my super desktop during testing. | ||
8252 | while (checkSimIsRunning(simd->tab)) | ||
8253 | usleep(100000); | ||
8254 | usleep(10000); | ||
8255 | doTmuxCmd("kill-pane -t %s", simd->paneID); | ||
8256 | I("Tmux tab [%d:%s](pane %d) tmux ID %s, from %s/sim%d - %s has stopped.", window, type, pane, simd->paneID, scTemp, count, simd->name); | ||
8257 | |||
8258 | count++; | ||
8259 | pane++; | ||
8260 | if (pane >= panes) | ||
8261 | { | ||
8262 | pane = 0; | ||
8263 | window++; | ||
8264 | } | ||
8265 | } | ||
8266 | } | ||
8267 | } | ||
8268 | q0->v.t->unlock(q0->v.t); | ||
8269 | } | ||
8270 | } | ||
8271 | ourSims->simsLua->unlock(ourSims->simsLua); | ||
8272 | |||
8273 | // Kill the rest of the panes that are not on the original window. | ||
8274 | I("Closing all the panes."); | ||
8275 | snprintf(toybuf, sizeof(toybuf), "echo 'IDs={' >%s/IDs_ALL.lua", scTemp); | 8129 | snprintf(toybuf, sizeof(toybuf), "echo 'IDs={' >%s/IDs_ALL.lua", scTemp); |
8276 | system(toybuf); | 8130 | system(toybuf); |
8277 | doTmuxCmd("list-panes -s -F '\"#{window_id}.#{pane_id}\",' >> %s/IDs_ALL.lua", scTemp); | 8131 | doTmuxCmd("list-panes -s -F '\"#{window_id}.#{pane_id}\",' >> %s/IDs_ALL.lua", scTemp); |
8278 | snprintf(toybuf, sizeof(toybuf), "echo '}\nreturn IDs' >>%s/IDs_ALL.lua", scTemp); | 8132 | snprintf(toybuf, sizeof(toybuf), "echo '}\nreturn IDs' >>%s/IDs_ALL.lua", scTemp); |
8279 | system(toybuf); | 8133 | system(toybuf); |
8280 | |||
8281 | snprintf(toybuf, sizeof(toybuf), "%s/IDs_ALL.lua", scTemp); | 8134 | snprintf(toybuf, sizeof(toybuf), "%s/IDs_ALL.lua", scTemp); |
8282 | qtreetbl_t *IDs = Lua2tree(toybuf, "IDs"); | 8135 | qtreetbl_t *IDs = Lua2tree(toybuf, "IDs"); |
8283 | 8136 | ||
8137 | qtreetbl_obj_t obj0; | ||
8284 | memset((void*)&obj0, 0, sizeof(obj0)); | 8138 | memset((void*)&obj0, 0, sizeof(obj0)); |
8285 | IDs->lock(IDs); | 8139 | IDs->lock(IDs); |
8286 | while(IDs->getnext(IDs, &obj0, false) == true) | 8140 | while(IDs->getnext(IDs, &obj0, false) == true) |
8287 | { | 8141 | { |
8288 | q0 = obj0.data; | 8142 | qLua *q0 = obj0.data; |
8143 | |||
8289 | if ('0' != q0->v.s[1]) | 8144 | if ('0' != q0->v.s[1]) |
8290 | doTmuxCmd("kill-pane -t %s", q0->v.s); | 8145 | doTmuxCmd("kill-pane -t %s", q0->v.s); |
8291 | } | 8146 | } |
@@ -8296,7 +8151,6 @@ fcgiDone: | |||
8296 | if (!WIFEXITED(system(c))) | 8151 | if (!WIFEXITED(system(c))) |
8297 | E("rm command failed! %s", c); | 8152 | E("rm command failed! %s", c); |
8298 | free(c); | 8153 | free(c); |
8299 | |||
8300 | } | 8154 | } |
8301 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 8155 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
8302 | // End of OpenSim wrangling section. | 8156 | // End of OpenSim wrangling section. |