home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / aegis-2.1 / part10 < prev    next >
Text File  |  1993-09-24  |  149KB  |  5,613 lines

  1. Newsgroups: comp.sources.unix
  2. From: pmiller@bmr.gov.au (Peter Miller)
  3. Subject: v27i045: aegis - project change supervisor (V2.1), Part10/19
  4. References: <1.748951883.12788@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: pmiller@bmr.gov.au (Peter Miller)
  9. Posting-Number: Volume 27, Issue 45
  10. Archive-Name: aegis-2.1/part10
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 10 (of 19)."
  19. # Contents:  aegis/aeb.c aegis/aeca.c aegis/aede.c aegis/aeif.c
  20. #   aegis/aemv.c aegis/aepa.c aegis/gonzo.c lib/aegis.pgm
  21. #   test/00/t0002a.sh
  22. # Wrapped by vixie@gw.home.vix.com on Sat Sep 25 03:00:43 1993
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'aegis/aeb.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'aegis/aeb.c'\"
  26. else
  27. echo shar: Extracting \"'aegis/aeb.c'\" \(14439 characters\)
  28. sed "s/^X//" >'aegis/aeb.c' <<'END_OF_FILE'
  29. X/*
  30. X *    aegis - project change supervisor
  31. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  32. X *    All rights reserved.
  33. X *
  34. X *    This program is free software; you can redistribute it and/or modify
  35. X *    it under the terms of the GNU General Public License as published by
  36. X *    the Free Software Foundation; either version 2 of the License, or
  37. X *    (at your option) any later version.
  38. X *
  39. X *    This program is distributed in the hope that it will be useful,
  40. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  41. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  42. X *    GNU General Public License for more details.
  43. X *
  44. X *    You should have received a copy of the GNU General Public License
  45. X *    along with this program; if not, write to the Free Software
  46. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  47. X *
  48. X * MANIFEST: functions to perform development and integration builds
  49. X */
  50. X
  51. X#include <stdio.h>
  52. X#include <stdlib.h>
  53. X#include <time.h>
  54. X#include <errno.h>
  55. X
  56. X#include <aeb.h>
  57. X#include <ael.h>
  58. X#include <arglex2.h>
  59. X#include <col.h>
  60. X#include <commit.h>
  61. X#include <change.h>
  62. X#include <error.h>
  63. X#include <error.h>
  64. X#include <help.h>
  65. X#include <lock.h>
  66. X#include <log.h>
  67. X#include <option.h>
  68. X#include <os.h>
  69. X#include <project.h>
  70. X#include <sub.h>
  71. X#include <trace.h>
  72. X#include <user.h>
  73. X
  74. X
  75. X/*
  76. X * NAME
  77. X *    build_usage
  78. X *
  79. X * SYNOPSIS
  80. X *    void build_usage(void);
  81. X *
  82. X * DESCRIPTION
  83. X *    The build_usage function is used to
  84. X *    briefly describe how to used the 'aegis -Build' command.
  85. X */
  86. X
  87. Xstatic void build_usage _((void));
  88. X
  89. Xstatic void
  90. Xbuild_usage()
  91. X{
  92. X    char        *progname;
  93. X
  94. X    progname = option_progname_get();
  95. X    fprintf(stderr, "usage: %s -Build [ <option>... ]\n", progname);
  96. X    fprintf(stderr, "       %s -Build -List [ <option>... ]\n", progname);
  97. X    fprintf(stderr, "       %s -Build -Help\n", progname);
  98. X    quit(1);
  99. X}
  100. X
  101. X
  102. X/*
  103. X * NAME
  104. X *    build_help
  105. X *
  106. X * SYNOPSIS
  107. X *    void build_help(void);
  108. X *
  109. X * DESCRIPTION
  110. X *    The build_help function is used to
  111. X *    describe in detail how to use the 'aegis -Build' command.
  112. X */
  113. X
  114. Xstatic void build_help _((void));
  115. X
  116. Xstatic void
  117. Xbuild_help()
  118. X{
  119. X    static char *text[] =
  120. X    {
  121. X"NAME",
  122. X"    %s -Build - build a project",
  123. X"",
  124. X"SYNOPSIS",
  125. X"    %s -Build [ option... ]",
  126. X"    %s -Build -List [ option... ]",
  127. X"    %s -Build -Help",
  128. X"",
  129. X"DESCRIPTION",
  130. X"    The %s -Build command is used to build a project.  The",
  131. X"    project configuration file is consulted for the",
  132. X"    appropriate build command, and that command is executed",
  133. X"    (see aepconf(5) for more information.)  Output of the",
  134. X"    command is automatically logged to the %s.log file at",
  135. X"    the root of the development directory tree.  The build",
  136. X"    command will be executed with its current directory being",
  137. X"    the root of the development directory, irrespective of",
  138. X"    there the %s -Build command was exectuted.",
  139. X"",
  140. X"    If the change is in the 'being_integrated' state,",
  141. X"    references to the development directory, above, should be",
  142. X"    read as the integration directory.  Integration build",
  143. X"    commands are executed with the user and group set to the",
  144. X"    project's owning user and group.  That is, it is not",
  145. X"    necessary for an integrator to log in as someone else,",
  146. X"    the project account for instance, in order to do an",
  147. X"    integration.",
  148. X"",
  149. X"    While there is a build in progress for any change in a",
  150. X"    project, an integrate pass for the project will wait until",
  151. X"    all the builds are completed before starting.  This is to",
  152. X"    ensure that the baseline is consistent for the entire build.",
  153. X"    Similarly, while an integrate pass is in progress for a",
  154. X"    project, any builds will wait until it is completed before",
  155. X"    starting.",
  156. X"",
  157. X"OPTIONS",
  158. X"    The following options are understood:",
  159. X"",
  160. X"    -Change <number>",
  161. X"        This option may be used to specify a particular",
  162. X"        change within a project.  When no -Change option is",
  163. X"        specified, the AEGIS_CHANGE environment variable is",
  164. X"        consulted.  If that does not exist, the user's",
  165. X"        $HOME/.aegisrc file is examined for a default change",
  166. X"        field (see aeuconf(5) for more information).  If",
  167. X"        that does not exist, when the user is only working",
  168. X"        on one change within a project, that is the default",
  169. X"        change number.  Otherwise, it is an error.",
  170. X"",
  171. X"    -Help",
  172. X"        This option may be used to obtain more",
  173. X"        information about how to use the %s program.",
  174. X"",
  175. X"    -List",
  176. X"        This option may be used to obtain a list of",
  177. X"        suitable subjects for this command.  The list may",
  178. X"        be more general than expected.",
  179. X"",
  180. X"    -Project <name>",
  181. X"        This option may be used to select the project of",
  182. X"        interest.  When no -Project option is specified, the",
  183. X"        AEGIS_PROJECT environment variable is consulted.  If",
  184. X"        that does not exist, the user's $HOME/.aegisrc file",
  185. X"        is examined for a default project field (see",
  186. X"        aeuconf(5) for more information).  If that does not",
  187. X"        exist, when the user is only working on changes",
  188. X"        within a single project, the project name defaults",
  189. X"        to that project.  Otherwise, it is an error.",
  190. X"",
  191. X"    -TERse",
  192. X"        This option may be used to cause listings to",
  193. X"        produce the bare minimum of information.  It is",
  194. X"        usually useful for shell scripts.",
  195. X"",
  196. X"    -Verbose",
  197. X"        This option may be used to cause %s to produce",
  198. X"        more output.  By default %s only produces",
  199. X"        output on errors.  When used with the -List",
  200. X"        option this option causes column headings to be",
  201. X"        added.",
  202. X"",
  203. X"    All options are case insensitive.  Options may be",
  204. X"    All options may be abbreviated; the abbreviation is",
  205. X"    documented as the upper case letters, all lower case",
  206. X"    letters and underscores (_) are optional.  You must use",
  207. X"    consecutive sequences of optional letters.",
  208. X"",
  209. X"    All options are case insensitive, you may type them in",
  210. X"    upper case or lower case or a combination of both, case",
  211. X"    is not important.",
  212. X"",
  213. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  214. X"    are all interpreted to mean the -Project option.  The",
  215. X"    argument \"-prj\" will not be understood, because",
  216. X"    consecutive optional characters were not supplied.",
  217. X"",
  218. X"    Options and other command line arguments may be mixed",
  219. X"    arbitrarily on the command line, after the function",
  220. X"    selectors.",
  221. X"",
  222. X"    The GNU long option names are understood.  Since all",
  223. X"    option names for aegis are long, this means ignoring the",
  224. X"    extra leading '-'.  The \"--option=value\" convention is",
  225. X"    also understood.",
  226. X"RECOMMENDED ALIAS",
  227. X"    The recommended alias for this command is",
  228. X"    csh%%    alias aeb '%s -b \\!* -v'",
  229. X"    sh$    aeb(){%s -b $* -v}",
  230. X"",
  231. X"ERRORS",
  232. X"    It is an error if the change is not assigned to the",
  233. X"    curent user.",
  234. X"    It is an error if the change is not in one of the",
  235. X"    'being_developed' or 'being_integrated' states.",
  236. X"",
  237. X"EXIT STATUS",
  238. X"    The %s command will exit with a status of 1 on any",
  239. X"    error.    The %s command will only exit with a status of",
  240. X"    0 if there are no errors.",
  241. X"",
  242. X"COPYRIGHT",
  243. X"    %C",
  244. X"",
  245. X"AUTHOR",
  246. X"    %A",
  247. X    };
  248. X
  249. X    help(text, SIZEOF(text), build_usage);
  250. X}
  251. X
  252. X
  253. X/*
  254. X * NAME
  255. X *    build_list
  256. X *
  257. X * SYNOPSIS
  258. X *    void build_list(void);
  259. X *
  260. X * DESCRIPTION
  261. X *    The build_list function is used to
  262. X *    list the changes which may be built within the project.
  263. X */
  264. X
  265. Xstatic void build_list _((void));
  266. X
  267. Xstatic void
  268. Xbuild_list()
  269. X{
  270. X    string_ty    *project_name;
  271. X
  272. X    trace(("build_list()\n{\n"/*}*/));
  273. X    arglex();
  274. X    project_name = 0;
  275. X    while (arglex_token != arglex_token_eoln)
  276. X    {
  277. X        switch (arglex_token)
  278. X        {
  279. X        default:
  280. X            generic_argument(build_usage);
  281. X            continue;
  282. X
  283. X        case arglex_token_project:
  284. X            if (arglex() != arglex_token_string)
  285. X                build_usage();
  286. X            if (project_name)
  287. X                fatal("duplicate -Project option");
  288. X            project_name = str_from_c(arglex_value.alv_string);
  289. X            break;
  290. X        }
  291. X        arglex();
  292. X    }
  293. X    list_changes_in_state_mask
  294. X    (
  295. X        project_name,
  296. X        (
  297. X            (1 << cstate_state_being_developed)
  298. X        |
  299. X            (1 << cstate_state_being_integrated)
  300. X        )
  301. X    );
  302. X    if (project_name)
  303. X        str_free(project_name);
  304. X    trace((/*{*/"}\n"));
  305. X}
  306. X
  307. X
  308. X/*
  309. X * NAME
  310. X *    build_main
  311. X *
  312. X * SYNOPSIS
  313. X *    void build_main(void);
  314. X *
  315. X * DESCRIPTION
  316. X *    The build_main function is used to
  317. X *    build a change in the "being developed" or "being integrated" states.
  318. X *    It extracts what to do from the command line.
  319. X */
  320. X
  321. Xstatic void build_main _((void));
  322. X
  323. Xstatic void
  324. Xbuild_main()
  325. X{
  326. X    string_ty    *the_command;
  327. X    cstate        cstate_data;
  328. X    pstate        pstate_data;
  329. X    pconf        pconf_data;
  330. X    string_ty    *project_name;
  331. X    project_ty    *pp;
  332. X    long        change_number;
  333. X    change_ty    *cp;
  334. X    int        nolog;
  335. X    user_ty        *up;
  336. X
  337. X    trace(("build_main()\n{\n"/*}*/));
  338. X    nolog = 0;
  339. X    project_name = 0;
  340. X    change_number = 0;
  341. X    while (arglex_token != arglex_token_eoln)
  342. X    {
  343. X        switch (arglex_token)
  344. X        {
  345. X        default:
  346. X            generic_argument(build_usage);
  347. X            continue;
  348. X
  349. X        case arglex_token_change:
  350. X            if (arglex() != arglex_token_number)
  351. X                build_usage();
  352. X            /* fall through... */
  353. X
  354. X        case arglex_token_number:
  355. X            if (change_number)
  356. X                fatal("duplicate -Change option");
  357. X            change_number = arglex_value.alv_number;
  358. X            if (change_number < 1)
  359. X                fatal("change %ld out of range", change_number);
  360. X            break;
  361. X
  362. X        case arglex_token_project:
  363. X            if (arglex() != arglex_token_string)
  364. X                build_usage();
  365. X            /* fall through... */
  366. X
  367. X        case arglex_token_string:
  368. X            if (project_name)
  369. X                fatal("duplicate -Project option");
  370. X            project_name = str_from_c(arglex_value.alv_string);
  371. X            break;
  372. X
  373. X        case arglex_token_nolog:
  374. X            if (nolog)
  375. X                fatal("duplicate %s option", arglex_value.alv_string);
  376. X            nolog = 1;
  377. X            break;
  378. X        }
  379. X        arglex();
  380. X    }
  381. X
  382. X    /*
  383. X     * locate project data
  384. X     */
  385. X    if (!project_name)
  386. X        project_name = user_default_project();
  387. X    pp = project_alloc(project_name);
  388. X    str_free(project_name);
  389. X    project_bind_existing(pp);
  390. X
  391. X    /*
  392. X     * locate user data
  393. X     */
  394. X    up = user_executing(pp);
  395. X
  396. X    /*
  397. X     * locate change data
  398. X     */
  399. X    if (!change_number)
  400. X        change_number = user_default_change(up);
  401. X    cp = change_alloc(pp, change_number);
  402. X    change_bind_existing(cp);
  403. X
  404. X    /*
  405. X     * Take an advisory write lock on this row of the change table.
  406. X     * Block if necessary.
  407. X     */
  408. X    change_cstate_lock_prepare(cp);
  409. X    project_build_read_lock_prepare(pp);
  410. X    lock_take();
  411. X    cstate_data = change_cstate_get(cp);
  412. X    pstate_data = project_pstate_get(pp);
  413. X
  414. X    /*
  415. X     * Extract the appropriate row of the change table.
  416. X     * It is an error if the change is not in the in-development state.
  417. X     * It is an error if the change is not assigned to the current user.
  418. X     * It is an error if the change has no files assigned.
  419. X     */
  420. X    switch (cstate_data->state)
  421. X    {
  422. X    default:
  423. X        change_fatal(cp, "not in 'being_developed' state");
  424. X        break;
  425. X
  426. X    case cstate_state_being_developed:
  427. X        if (!str_equal(change_developer_name(cp), user_name(up)))
  428. X        {
  429. X            change_fatal
  430. X            (
  431. X                cp,
  432. X                "user \"%S\" is not the developer",
  433. X                user_name(up)
  434. X            );
  435. X        }
  436. X        assert(cstate_data->src);
  437. X        if (!cstate_data->src->length)
  438. X            change_fatal(cp, "has no files");
  439. X        break;
  440. X
  441. X    case cstate_state_being_integrated:
  442. X        if (!str_equal(change_integrator_name(cp), user_name(up)))
  443. X        {
  444. X            change_fatal
  445. X            (
  446. X                cp,
  447. X                "user \"%S\" is not the integrator",
  448. X                user_name(up)
  449. X            );
  450. X        }
  451. X        break;
  452. X    }
  453. X
  454. X    /*
  455. X     * Update the time the build was done.
  456. X     * This will not be written out if the build fails.
  457. X     */
  458. X    time(&cstate_data->build_time);
  459. X
  460. X    /*
  461. X     * get the command to execute
  462. X     *  1. if the change is editing config, use that
  463. X     *  2. if the baseline contains config, use that
  464. X     *  3. error if can't find one (DON'T look for file existence)
  465. X     */
  466. X    pconf_data = change_pconf_get(cp);
  467. X    if
  468. X    (
  469. X        !pconf_data->development_build_command
  470. X    ||
  471. X        !pconf_data->build_command
  472. X    )
  473. X    {
  474. X        change_fatal
  475. X        (
  476. X            cp,
  477. X            "you need to create a new \"%s\" file before you can build",
  478. X            THE_CONFIG_FILE
  479. X        );
  480. X    }
  481. X
  482. X    /*
  483. X     * work out the build command
  484. X     */
  485. X    trace(("work out the build command\n"));
  486. X    if (cstate_data->state == cstate_state_being_integrated)
  487. X    {
  488. X        /*
  489. X         * %1 = project name
  490. X         * %2 = change number
  491. X         * %3 = identifying string, in the form "a.b.Dnnn"
  492. X         *    where 'a' is the major version number,
  493. X         *    'b' is the minor version number,
  494. X         *    and 'nnn' is the build number.
  495. X         */
  496. X        sub_var_set("1", "${project}");
  497. X        sub_var_set("2", "${change}");
  498. X        sub_var_set("3", "${version}");
  499. X        the_command = pconf_data->build_command;
  500. X        the_command = substitute(cp, the_command);
  501. X    }
  502. X    else
  503. X    {
  504. X        /*
  505. X         * %1 = project name
  506. X         * %2 = change number
  507. X         * %3 = identifying string, in the form "a.b.Cnnn"
  508. X         *    where 'a' is the major version number,
  509. X         *    'b' is the minor version number,
  510. X         *    and 'nnn' is the change number.
  511. X         * %4 = the absolute path of the project baseline directory.
  512. X         */
  513. X        sub_var_set("1", "${project}");
  514. X        sub_var_set("2", "${change}");
  515. X        sub_var_set("3", "${version}");
  516. X        sub_var_set("4", "${baseline}");
  517. X        the_command = pconf_data->development_build_command;
  518. X        the_command = substitute(cp, the_command);
  519. X    }
  520. X
  521. X    /*
  522. X     * the program has changed, so it needs testing again,
  523. X     * so stomp on the validation fields.
  524. X     */
  525. X    trace(("nuke time stamps\n"));
  526. X    cstate_data->test_time = 0;
  527. X    cstate_data->regression_test_time = 0;
  528. X    cstate_data->test_baseline_time = 0;
  529. X
  530. X    /*
  531. X     * do the build
  532. X     */
  533. X    trace(("open the log file\n"));
  534. X    trace(("do the build\n"));
  535. X    if (cstate_data->state == cstate_state_being_integrated)
  536. X    {
  537. X        string_ty    *id;
  538. X
  539. X        if (!nolog)
  540. X        {
  541. X            user_ty        *pup;
  542. X
  543. X            pup = project_user(pp);
  544. X            log_open(change_logfile_get(cp), pup);
  545. X            user_free(pup);
  546. X        }
  547. X        change_verbose(cp, "integration build started");
  548. X        id = change_integration_directory_get(cp, 0);
  549. X        project_become(pp);
  550. X        os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
  551. X        project_become_undo();
  552. X        change_verbose(cp, "integration build complete");
  553. X    }
  554. X    else
  555. X    {
  556. X        string_ty    *dd;
  557. X
  558. X        if (!nolog)
  559. X            log_open(change_logfile_get(cp), up);
  560. X        change_verbose(cp, "development build started");
  561. X        change_run_project_file_command(cp);
  562. X        dd = change_development_directory_get(cp, 0);
  563. X        user_become(up);
  564. X        os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
  565. X        user_become_undo();
  566. X        change_verbose(cp, "development build complete");
  567. X    }
  568. X
  569. X    /*
  570. X     * Update change data with result of build.
  571. X     * (This will be used when validating developer sign off.)
  572. X     * Release advisory write lock on row of change table.
  573. X     */
  574. X    change_cstate_write(cp);
  575. X    commit();
  576. X    lock_release();
  577. X    project_free(pp);
  578. X    change_free(cp);
  579. X    user_free(up);
  580. X    trace((/*{*/"}\n"));
  581. X}
  582. X
  583. X
  584. X/*
  585. X * NAME
  586. X *    build
  587. X *
  588. X * SYNOPSIS
  589. X *    void build(void);
  590. X *
  591. X * DESCRIPTION
  592. X *    The build function is used to
  593. X *    dispatch the 'aegis -Build' command to the relevant functionality.
  594. X *    Where it goes depends on the command line.
  595. X */
  596. X
  597. Xvoid
  598. Xbuild()
  599. X{
  600. X    trace(("build()\n{\n"/*}*/));
  601. X    switch (arglex())
  602. X    {
  603. X    default:
  604. X        build_main();
  605. X        break;
  606. X
  607. X    case arglex_token_help:
  608. X        build_help();
  609. X        break;
  610. X
  611. X    case arglex_token_list:
  612. X        build_list();
  613. X        break;
  614. X    }
  615. X    trace((/*{*/"}\n"));
  616. X}
  617. END_OF_FILE
  618. if test 14439 -ne `wc -c <'aegis/aeb.c'`; then
  619.     echo shar: \"'aegis/aeb.c'\" unpacked with wrong size!
  620. fi
  621. # end of 'aegis/aeb.c'
  622. fi
  623. if test -f 'aegis/aeca.c' -a "${1}" != "-c" ; then 
  624.   echo shar: Will not clobber existing file \"'aegis/aeca.c'\"
  625. else
  626. echo shar: Extracting \"'aegis/aeca.c'\" \(14427 characters\)
  627. sed "s/^X//" >'aegis/aeca.c' <<'END_OF_FILE'
  628. X/*
  629. X *    aegis - project change supervisor
  630. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  631. X *    All rights reserved.
  632. X *
  633. X *    This program is free software; you can redistribute it and/or modify
  634. X *    it under the terms of the GNU General Public License as published by
  635. X *    the Free Software Foundation; either version 2 of the License, or
  636. X *    (at your option) any later version.
  637. X *
  638. X *    This program is distributed in the hope that it will be useful,
  639. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  640. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  641. X *    GNU General Public License for more details.
  642. X *
  643. X *    You should have received a copy of the GNU General Public License
  644. X *    along with this program; if not, write to the Free Software
  645. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  646. X *
  647. X * MANIFEST: functions to list and modify change attributes
  648. X */
  649. X
  650. X#include <stdio.h>
  651. X#include <stdlib.h>
  652. X
  653. X#include <aeca.h>
  654. X#include <arglex2.h>
  655. X#include <cattr.h>
  656. X#include <commit.h>
  657. X#include <change.h>
  658. X#include <error.h>
  659. X#include <help.h>
  660. X#include <lock.h>
  661. X#include <project.h>
  662. X#include <option.h>
  663. X#include <os.h>
  664. X#include <trace.h>
  665. X#include <user.h>
  666. X
  667. X
  668. Xstatic void change_attributes_usage _((void));
  669. X
  670. Xstatic void
  671. Xchange_attributes_usage()
  672. X{
  673. X    char        *progname;
  674. X
  675. X    progname = option_progname_get();
  676. X    fprintf(stderr, "usage: %s -Change_Attributes <attr-file> [ <option>... ]\n", progname);
  677. X    fprintf(stderr, "       %s -Change_Attributes -Edit [ <option>... ]\n", progname);
  678. X    fprintf(stderr, "       %s -Change_Attributes -List [ <option>... ]\n", progname);
  679. X    fprintf(stderr, "       %s -Change_Attributes -Help\n", progname);
  680. X    quit(1);
  681. X}
  682. X
  683. X
  684. Xstatic void change_attributes_help _((void));
  685. X
  686. Xstatic void
  687. Xchange_attributes_help()
  688. X{
  689. X    static char *text[] =
  690. X    {
  691. X"NAME",
  692. X"    %s -Change_Attributes - modify the attributes of a",
  693. X"    change",
  694. X"",
  695. X"SYNOPSIS",
  696. X"    %s -Change_Attributes <attr-file> [ <option>... ]",
  697. X"    %s -Change_Attributes -Edit [ <option>... ]",
  698. X"    %s -Change_Attributes -List [ <option>... ]",
  699. X"    %s -Change_Attributes -Help",
  700. X"",
  701. X"DESCRIPTION",
  702. X"    The %s -Change_Attributes command is used to set, edit",
  703. X"    or list the attributes of a change.",
  704. X"",
  705. X"    The output of the -List variant is suitable for use as",
  706. X"    input at a later time.",
  707. X"",
  708. X"    See aecattr(5) for a description of the file format.",
  709. X"",
  710. X"OPTIONS",
  711. X"    The following options are understood:",
  712. X"",
  713. X"    -Change <number>",
  714. X"        This option may be used to specify a particular",
  715. X"        change within a project.  When no -Change option is",
  716. X"        specified, the AEGIS_CHANGE environment variable is",
  717. X"        consulted.  If that does not exist, the user's",
  718. X"        $HOME/.aegisrc file is examined for a default change",
  719. X"        field (see aeuconf(5) for more information).  If",
  720. X"        that does not exist, when the user is only working",
  721. X"        on one change within a project, that is the default",
  722. X"        change number.  Otherwise, it is an error.",
  723. X"",
  724. X"    -Edit",
  725. X"        Edit the attributes with a text editor, this is",
  726. X"        usually more convenient than supplying a text",
  727. X"        file.  The EDITOR environment variable will be",
  728. X"        consulted for the name of the editor to use;",
  729. X"        defaults to vi(1) if not set.  Warning: not well",
  730. X"        behaved when faced with errors, the temporary",
  731. X"        file is always deleted.",
  732. X"",
  733. X"    -Help",
  734. X"        This option may be used to obtain more",
  735. X"        information about how to use the %s program.",
  736. X"",
  737. X"    -List",
  738. X"        This option may be used to obtain a list of",
  739. X"        suitable subjects for this command.  The list may",
  740. X"        be more general than expected.",
  741. X"",
  742. X"    -Project <name>",
  743. X"        This option may be used to select the project of",
  744. X"        interest.  When no -Project option is specified, the",
  745. X"        AEGIS_PROJECT environment variable is consulted.  If",
  746. X"        that does not exist, the user's $HOME/.aegisrc file",
  747. X"        is examined for a default project field (see",
  748. X"        aeuconf(5) for more information).  If that does not",
  749. X"        exist, when the user is only working on changes",
  750. X"        within a single project, the project name defaults",
  751. X"        to that project.  Otherwise, it is an error.",
  752. X"",
  753. X"    -TERse",
  754. X"        This option may be used to cause listings to",
  755. X"        produce the bare minimum of information.  It is",
  756. X"        usually useful for shell scripts.",
  757. X"",
  758. X"    -Verbose",
  759. X"        This option may be used to cause %s to produce",
  760. X"        more output.  By default %s only produces",
  761. X"        output on errors.  When used with the -List",
  762. X"        option this option causes column headings to be",
  763. X"        added.",
  764. X"",
  765. X"    All options may be abbreviated; the abbreviation is",
  766. X"    documented as the upper case letters, all lower case",
  767. X"    letters and underscores (_) are optional.  You must use",
  768. X"    consecutive sequences of optional letters.",
  769. X"",
  770. X"    All options are case insensitive, you may type them in",
  771. X"    upper case or lower case or a combination of both, case",
  772. X"    is not important.",
  773. X"",
  774. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  775. X"    are all interpreted to mean the -Project option.  The",
  776. X"    argument \"-prj\" will not be understood, because",
  777. X"    consecutive optional characters were not supplied.",
  778. X"",
  779. X"    Options and other command line arguments may be mixed",
  780. X"    arbitrarily on the command line, after the function",
  781. X"    selectors.",
  782. X"",
  783. X"    The GNU long option names are understood.  Since all",
  784. X"    option names for aegis are long, this means ignoring the",
  785. X"    extra leading '-'.  The \"--option=value\" convention is",
  786. X"    also understood.",
  787. X"",
  788. X"RECOMMENDED ALIAS",
  789. X"    The recommended alias for this command is",
  790. X"    csh%%    alias aeca '%s -ca \\!* -v'",
  791. X"    sh$    aeca(){%s -ca $* -v}",
  792. X"",
  793. X"ERRORS",
  794. X"    It is an error if the current user is not an",
  795. X"    administrator of the specified project.",
  796. X"",
  797. X"EXIT STATUS",
  798. X"    The %s command will exit with a status of 1 on any",
  799. X"    error.    The %s command will only exit with a status of",
  800. X"    0 if there are no errors.",
  801. X"",
  802. X"COPYRIGHT",
  803. X"    %C",
  804. X"",
  805. X"AUTHOR",
  806. X"    %A",
  807. X    };
  808. X
  809. X    help(text, SIZEOF(text), change_attributes_usage);
  810. X}
  811. X
  812. X
  813. Xstatic void cattr_copy _((cattr, cstate));
  814. X
  815. Xstatic void
  816. Xcattr_copy(a, s)
  817. X    cattr    a;
  818. X    cstate    s;
  819. X{
  820. X    if (!a->description && s->description)
  821. X    {
  822. X        a->description = str_copy(s->description);
  823. X        a->mask |= cattr_description_mask;
  824. X    }
  825. X    if (!a->brief_description && s->brief_description)
  826. X    {
  827. X        a->brief_description = str_copy(s->brief_description);
  828. X        a->mask |= cattr_brief_description_mask;
  829. X    }
  830. X    if (!(a->mask & cattr_cause_mask))
  831. X    {
  832. X        a->cause = s->cause;
  833. X        a->mask |= cattr_cause_mask;
  834. X    }
  835. X    if (!(a->mask & cattr_regression_test_exempt_mask))
  836. X    {
  837. X        a->regression_test_exempt = s->regression_test_exempt;
  838. X        a->mask |= cattr_regression_test_exempt_mask;
  839. X    }
  840. X    if (!(a->mask & cattr_test_exempt_mask))
  841. X    {
  842. X        a->test_exempt = s->test_exempt;
  843. X        a->mask |= cattr_test_exempt_mask;
  844. X    }
  845. X    if (!(a->mask & cattr_test_baseline_exempt_mask))
  846. X    {
  847. X        a->test_baseline_exempt = s->test_baseline_exempt;
  848. X        a->mask |= cattr_test_baseline_exempt_mask;
  849. X    }
  850. X}
  851. X
  852. X
  853. Xstatic void change_attributes_list _((void));
  854. X
  855. Xstatic void
  856. Xchange_attributes_list()
  857. X{
  858. X    string_ty    *project_name;
  859. X    project_ty    *pp;
  860. X    cattr        cattr_data;
  861. X    cstate        cstate_data;
  862. X    long        change_number;
  863. X    change_ty    *cp;
  864. X    user_ty        *up;
  865. X
  866. X    trace(("change_attributes_list()\n{\n"/*}*/));
  867. X    arglex();
  868. X    project_name = 0;
  869. X    change_number = 0;
  870. X    while (arglex_token != arglex_token_eoln)
  871. X    {
  872. X        switch (arglex_token)
  873. X        {
  874. X        default:
  875. X            generic_argument(change_attributes_usage);
  876. X            continue;
  877. X
  878. X        case arglex_token_change:
  879. X            if (arglex() != arglex_token_number)
  880. X                change_attributes_usage();
  881. X            /* fall through... */
  882. X
  883. X        case arglex_token_number:
  884. X            if (change_number)
  885. X                fatal("duplicate -Change option");
  886. X            change_number = arglex_value.alv_number;
  887. X            if (change_number < 1)
  888. X                fatal("change %ld out of range", change_number);
  889. X            break;
  890. X
  891. X        case arglex_token_project:
  892. X            if (arglex() != arglex_token_string)
  893. X                change_attributes_usage();
  894. X            if (project_name)
  895. X                fatal("duplicate -Project option");
  896. X            project_name = str_from_c(arglex_value.alv_string);
  897. X            break;
  898. X        }
  899. X        arglex();
  900. X    }
  901. X
  902. X    /*
  903. X     * locate project data
  904. X     */
  905. X    if (!project_name)
  906. X        project_name = user_default_project();
  907. X    pp = project_alloc(project_name);
  908. X    str_free(project_name);
  909. X    project_bind_existing(pp);
  910. X
  911. X    /*
  912. X     * locate user data
  913. X     */
  914. X    up = user_executing(pp);
  915. X
  916. X    /*
  917. X     * locate change data
  918. X     */
  919. X    if (!change_number)
  920. X        change_number = user_default_change(up);
  921. X    cp = change_alloc(pp, change_number);
  922. X    change_bind_existing(cp);
  923. X
  924. X    /*
  925. X     * build the cattr data
  926. X     */
  927. X    cstate_data = change_cstate_get(cp);
  928. X    cattr_data = (cattr)cattr_type.alloc();
  929. X    cattr_copy(cattr_data, cstate_data);
  930. X
  931. X    /*
  932. X     * print the cattr data
  933. X     */
  934. X    cattr_write_file((char *)0, cattr_data);
  935. X    cattr_type.free(cattr_data);
  936. X    project_free(pp);
  937. X    change_free(cp);
  938. X    user_free(up);
  939. X    trace((/*{*/"}\n"));
  940. X}
  941. X
  942. X
  943. Xvoid
  944. Xcattr_verify(fn, d)
  945. X    char        *fn;
  946. X    cattr        d;
  947. X{
  948. X    if (!d->brief_description)
  949. X        fatal("%s: contains no \"brief_description\" field", fn);
  950. X    if (!(d->mask & cattr_cause_mask))
  951. X        fatal("%s: contains no \"cause\" field", fn);
  952. X}
  953. X
  954. X
  955. Xvoid
  956. Xcattr_edit(dp)
  957. X    cattr        *dp;
  958. X{
  959. X    cattr        d;
  960. X    string_ty    *filename;
  961. X    
  962. X    /*
  963. X     * write attributes to temporary file
  964. X     */
  965. X    d = *dp;
  966. X    assert(d);
  967. X    filename = os_edit_filename();
  968. X    os_become_orig();
  969. X    cattr_write_file(filename->str_text, d);
  970. X    cattr_type.free(d);
  971. X
  972. X    /*
  973. X     * edit the file
  974. X     */
  975. X    os_edit(filename);
  976. X
  977. X    /*
  978. X     * read it in again
  979. X     */
  980. X    d = cattr_read_file(filename->str_text);
  981. X    os_unlink(filename);
  982. X    os_become_undo();
  983. X    cattr_verify(filename->str_text, d);
  984. X    str_free(filename);
  985. X    *dp = d;
  986. X}
  987. X
  988. X
  989. Xstatic void change_attributes_main _((void));
  990. X
  991. Xstatic void
  992. Xchange_attributes_main()
  993. X{
  994. X    string_ty    *project_name;
  995. X    project_ty    *pp;
  996. X    cattr        cattr_data = 0;
  997. X    cstate        cstate_data;
  998. X    long        change_number;
  999. X    change_ty    *cp;
  1000. X    user_ty        *up;
  1001. X    int        edit;
  1002. X
  1003. X    trace(("change_attributes_main()\n{\n"/*}*/));
  1004. X    project_name = 0;
  1005. X    change_number = 0;
  1006. X    edit = 0;
  1007. X    while (arglex_token != arglex_token_eoln)
  1008. X    {
  1009. X        switch (arglex_token)
  1010. X        {
  1011. X        default:
  1012. X            generic_argument(change_attributes_usage);
  1013. X            continue;
  1014. X
  1015. X        case arglex_token_string:
  1016. X            if (cattr_data)
  1017. X                fatal("too many files named");
  1018. X            os_become_orig();
  1019. X            cattr_data = cattr_read_file(arglex_value.alv_string);
  1020. X            os_become_undo();
  1021. X            assert(cattr_data);
  1022. X            break;
  1023. X
  1024. X        case arglex_token_change:
  1025. X            if (arglex() != arglex_token_number)
  1026. X                change_attributes_usage();
  1027. X            /* fall through... */
  1028. X
  1029. X        case arglex_token_number:
  1030. X            if (change_number)
  1031. X                fatal("duplicate -Change option");
  1032. X            change_number = arglex_value.alv_number;
  1033. X            if (change_number < 1)
  1034. X                fatal("change %ld out of range", change_number);
  1035. X            break;
  1036. X
  1037. X        case arglex_token_project:
  1038. X            if (arglex() != arglex_token_string)
  1039. X                change_attributes_usage();
  1040. X            if (project_name)
  1041. X                fatal("duplicate -Project option");
  1042. X            project_name = str_from_c(arglex_value.alv_string);
  1043. X            break;
  1044. X
  1045. X        case arglex_token_edit:
  1046. X            if (edit)
  1047. X                fatal("duplicate \"%s\" option", arglex_value.alv_string);
  1048. X            edit++;
  1049. X            break;
  1050. X        }
  1051. X        arglex();
  1052. X    }
  1053. X    if (edit && !cattr_data)
  1054. X        cattr_data = (cattr)cattr_type.alloc();
  1055. X    if (!cattr_data)
  1056. X        fatal("no file named");
  1057. X
  1058. X    /*
  1059. X     * locate project data
  1060. X     */
  1061. X    if (!project_name)
  1062. X        project_name = user_default_project();
  1063. X    pp = project_alloc(project_name);
  1064. X    str_free(project_name);
  1065. X    project_bind_existing(pp);
  1066. X
  1067. X    /*
  1068. X     * locate user data
  1069. X     */
  1070. X    up = user_executing(pp);
  1071. X
  1072. X    /*
  1073. X     * locate change data
  1074. X     */
  1075. X    if (!change_number)
  1076. X        change_number = user_default_change(up);
  1077. X    cp = change_alloc(pp, change_number);
  1078. X    change_bind_existing(cp);
  1079. X
  1080. X    /*
  1081. X     * edit the attributes
  1082. X     */
  1083. X    if (edit)
  1084. X    {
  1085. X        /*
  1086. X         * fill in any other fields
  1087. X         */
  1088. X        cstate_data = change_cstate_get(cp);
  1089. X        cattr_copy(cattr_data, cstate_data);
  1090. X
  1091. X        /*
  1092. X         * edit the attributes
  1093. X         */
  1094. X        cattr_edit(&cattr_data);
  1095. X    }
  1096. X
  1097. X    /*
  1098. X     * lock the change
  1099. X     */
  1100. X    change_cstate_lock_prepare(cp);
  1101. X    lock_take();
  1102. X    cstate_data = change_cstate_get(cp);
  1103. X
  1104. X    /*
  1105. X     * It is an error if the change is not in the "being developed" state.
  1106. X     * It is an error if the user is not an administrator or the developer.
  1107. X     */
  1108. X    if
  1109. X    (
  1110. X        !project_administrator_query(pp, user_name(up))
  1111. X    &&
  1112. X        (
  1113. X            cstate_data->state != cstate_state_being_developed
  1114. X        ||
  1115. X            !str_equal(change_developer_name(cp), user_name(up))
  1116. X        )
  1117. X    )
  1118. X    {
  1119. X        change_fatal
  1120. X        (
  1121. X            cp,
  1122. X            "attributes may only be changed by a project \
  1123. Xadministrator, or by the developer during development"
  1124. X        );
  1125. X    }
  1126. X
  1127. X    /*
  1128. X     * copy the attributes across
  1129. X     */
  1130. X    if (cattr_data->description)
  1131. X    {
  1132. X        if (cstate_data->description)
  1133. X            str_free(cstate_data->description);
  1134. X        cstate_data->description = str_copy(cattr_data->description);
  1135. X    }
  1136. X    if (cattr_data->brief_description)
  1137. X    {
  1138. X        if (cstate_data->brief_description)
  1139. X            str_free(cstate_data->brief_description);
  1140. X        cstate_data->brief_description =
  1141. X            str_copy(cattr_data->brief_description);
  1142. X    }
  1143. X    if (cattr_data->mask & cattr_cause_mask)
  1144. X        cstate_data->cause = cattr_data->cause;
  1145. X    if (project_administrator_query(pp, user_name(up)))
  1146. X    {
  1147. X        if (cattr_data->mask & cattr_test_exempt_mask)
  1148. X            cstate_data->test_exempt = cattr_data->test_exempt;
  1149. X        if (cattr_data->mask & cattr_test_baseline_exempt_mask)
  1150. X            cstate_data->test_baseline_exempt =
  1151. X                cattr_data->test_baseline_exempt;
  1152. X        if (cattr_data->mask & cattr_regression_test_exempt_mask)
  1153. X            cstate_data->regression_test_exempt =
  1154. X                cattr_data->regression_test_exempt;
  1155. X    }
  1156. X    else
  1157. X    {
  1158. X        if
  1159. X        (
  1160. X            (
  1161. X                cattr_data->test_exempt
  1162. X            &&
  1163. X                !cstate_data->test_exempt
  1164. X            )
  1165. X        ||
  1166. X            (
  1167. X                cattr_data->test_baseline_exempt
  1168. X            &&
  1169. X                !cstate_data->test_baseline_exempt
  1170. X            )
  1171. X        ||
  1172. X            (
  1173. X                cattr_data->regression_test_exempt
  1174. X            &&
  1175. X                !cstate_data->regression_test_exempt
  1176. X            )
  1177. X        )
  1178. X        {
  1179. X            change_fatal
  1180. X            (
  1181. X                cp,
  1182. X           "only project administrators may exempt changes from testing"
  1183. X            );
  1184. X        }
  1185. X        else
  1186. X        {
  1187. X            /*
  1188. X             * developers may remove exemptions
  1189. X             */
  1190. X            if
  1191. X            (
  1192. X                (cattr_data->mask & cattr_test_exempt_mask)
  1193. X            &&
  1194. X                !cattr_data->test_exempt
  1195. X            )
  1196. X                cstate_data->test_exempt = 0;
  1197. X            if
  1198. X            (
  1199. X                (cattr_data->mask & cattr_test_baseline_exempt_mask)
  1200. X            &&
  1201. X                !cattr_data->test_baseline_exempt
  1202. X            )
  1203. X                cstate_data->test_baseline_exempt = 0;
  1204. X            if
  1205. X            (
  1206. X                (cattr_data->mask & cattr_regression_test_exempt_mask)
  1207. X            &&
  1208. X                !cattr_data->regression_test_exempt
  1209. X            )
  1210. X                cstate_data->regression_test_exempt = 0;
  1211. X        }
  1212. X    }
  1213. X
  1214. X    cattr_type.free(cattr_data);
  1215. X    change_cstate_write(cp);
  1216. X    commit();
  1217. X    lock_release();
  1218. X    change_verbose(cp, "attributes changed");
  1219. X    project_free(pp);
  1220. X    change_free(cp);
  1221. X    user_free(up);
  1222. X    trace((/*{*/"}\n"));
  1223. X}
  1224. X
  1225. X
  1226. Xvoid
  1227. Xchange_attributes()
  1228. X{
  1229. X    trace(("change_attributes()\n{\n"/*}*/));
  1230. X    switch (arglex())
  1231. X    {
  1232. X    default:
  1233. X        change_attributes_main();
  1234. X        break;
  1235. X
  1236. X    case arglex_token_help:
  1237. X        change_attributes_help();
  1238. X        break;
  1239. X
  1240. X    case arglex_token_list:
  1241. X        change_attributes_list();
  1242. X        break;
  1243. X    }
  1244. X    trace((/*{*/"}\n"));
  1245. X}
  1246. END_OF_FILE
  1247. if test 14427 -ne `wc -c <'aegis/aeca.c'`; then
  1248.     echo shar: \"'aegis/aeca.c'\" unpacked with wrong size!
  1249. fi
  1250. # end of 'aegis/aeca.c'
  1251. fi
  1252. if test -f 'aegis/aede.c' -a "${1}" != "-c" ; then 
  1253.   echo shar: Will not clobber existing file \"'aegis/aede.c'\"
  1254. else
  1255. echo shar: Extracting \"'aegis/aede.c'\" \(17211 characters\)
  1256. sed "s/^X//" >'aegis/aede.c' <<'END_OF_FILE'
  1257. X/*
  1258. X *    aegis - project change supervisor
  1259. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  1260. X *    All rights reserved.
  1261. X *
  1262. X *    This program is free software; you can redistribute it and/or modify
  1263. X *    it under the terms of the GNU General Public License as published by
  1264. X *    the Free Software Foundation; either version 2 of the License, or
  1265. X *    (at your option) any later version.
  1266. X *
  1267. X *    This program is distributed in the hope that it will be useful,
  1268. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1269. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1270. X *    GNU General Public License for more details.
  1271. X *
  1272. X *    You should have received a copy of the GNU General Public License
  1273. X *    along with this program; if not, write to the Free Software
  1274. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1275. X *
  1276. X * MANIFEST: functions to implement develop end
  1277. X */
  1278. X
  1279. X#include <stdio.h>
  1280. X#include <stdlib.h>
  1281. X#include <string.h>
  1282. X#include <time.h>
  1283. X#include <sys/types.h>
  1284. X#include <sys/stat.h>
  1285. X
  1286. X#include <aede.h>
  1287. X#include <ael.h>
  1288. X#include <arglex2.h>
  1289. X#include <change.h>
  1290. X#include <col.h>
  1291. X#include <commit.h>
  1292. X#include <common.h>
  1293. X#include <dir.h>
  1294. X#include <error.h>
  1295. X#include <help.h>
  1296. X#include <lock.h>
  1297. X#include <option.h>
  1298. X#include <os.h>
  1299. X#include <project.h>
  1300. X#include <sub.h>
  1301. X#include <trace.h>
  1302. X#include <undo.h>
  1303. X#include <user.h>
  1304. X
  1305. X
  1306. Xstatic void develop_end_usage _((void));
  1307. X
  1308. Xstatic void
  1309. Xdevelop_end_usage()
  1310. X{
  1311. X    char        *progname;
  1312. X
  1313. X    progname = option_progname_get();
  1314. X    fprintf(stderr, "usage: %s -Develop_End [ <option>... ]\n", progname);
  1315. X    fprintf(stderr, "       %s -Develop_End -List [ <option>... ]\n", progname);
  1316. X    fprintf(stderr, "       %s -Develop_End -Help\n", progname);
  1317. X    quit(1);
  1318. X}
  1319. X
  1320. X
  1321. Xstatic void develop_end_help _((void));
  1322. X
  1323. Xstatic void
  1324. Xdevelop_end_help()
  1325. X{
  1326. X    static char *text[] =
  1327. X    {
  1328. X"NAME",
  1329. X"    %s -Develop_End - complete development of a change",
  1330. X"",
  1331. X"SYNOPSIS",
  1332. X"    %s -Develop_End [ <option>... ]",
  1333. X"    %s -Develop_End -List [ <option>... ]",
  1334. X"    %s -Develop_End -Help",
  1335. X"",
  1336. X"DESCRIPTION",
  1337. X"    The %s -Develop_End command is used to notify",
  1338. X"    %s of the completion of the development of a change.",
  1339. X"",
  1340. X"    Successful execution of the command advances the change",
  1341. X"    from the 'being_developed' state to the 'being_reviewed'",
  1342. X"    state.",
  1343. X"",
  1344. X"    The ownership of files in the development directory is",
  1345. X"    changed to the project owner and group, and the files",
  1346. X"    changed to be read-only.  This prevents accidental",
  1347. X"    alterations of the change's files between development and",
  1348. X"    integration.",
  1349. X"",
  1350. X"    The change is no longer considered assigned to the",
  1351. X"    current user.",
  1352. X"",
  1353. X"OPTIONS",
  1354. X"    The following options are understood:",
  1355. X"",
  1356. X"    -Change <number>",
  1357. X"        This option may be used to specify a particular",
  1358. X"        change within a project.  When no -Change option is",
  1359. X"        specified, the AEGIS_CHANGE environment variable is",
  1360. X"        consulted.  If that does not exist, the user's",
  1361. X"        $HOME/.aegisrc file is examined for a default change",
  1362. X"        field (see aeuconf(5) for more information).  If",
  1363. X"        that does not exist, when the user is only working",
  1364. X"        on one change within a project, that is the default",
  1365. X"        change number.  Otherwise, it is an error.",
  1366. X"",
  1367. X"    -Help",
  1368. X"        This option may be used to obtain more",
  1369. X"        information about how to use the %s program.",
  1370. X"",
  1371. X"    -List",
  1372. X"        This option may be used to obtain a list of",
  1373. X"        suitable subjects for this command.  The list may",
  1374. X"        be more general than expected.",
  1375. X"",
  1376. X"    -Project <name>",
  1377. X"        This option may be used to select the project of",
  1378. X"        interest.  When no -Project option is specified, the",
  1379. X"        AEGIS_PROJECT environment variable is consulted.  If",
  1380. X"        that does not exist, the user's $HOME/.aegisrc file",
  1381. X"        is examined for a default project field (see",
  1382. X"        aeuconf(5) for more information).  If that does not",
  1383. X"        exist, when the user is only working on changes",
  1384. X"        within a single project, the project name defaults",
  1385. X"        to that project.  Otherwise, it is an error.",
  1386. X"",
  1387. X"    -TERse",
  1388. X"        This option may be used to cause listings to",
  1389. X"        produce the bare minimum of information.  It is",
  1390. X"        usually useful for shell scripts.",
  1391. X"",
  1392. X"    -Verbose",
  1393. X"        This option may be used to cause %s to produce",
  1394. X"        more output.  By default %s only produces",
  1395. X"        output on errors.  When used with the -List",
  1396. X"        option this option causes column headings to be",
  1397. X"        added.",
  1398. X"",
  1399. X"    All options may be abbreviated; the abbreviation is",
  1400. X"    documented as the upper case letters, all lower case",
  1401. X"    letters and underscores (_) are optional.  You must use",
  1402. X"    consecutive sequences of optional letters.",
  1403. X"",
  1404. X"    All options are case insensitive, you may type them in",
  1405. X"    upper case or lower case or a combination of both, case",
  1406. X"    is not important.",
  1407. X"",
  1408. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  1409. X"    are all interpreted to mean the -Project option.  The",
  1410. X"    argument \"-prj\" will not be understood, because",
  1411. X"    consecutive optional characters were not supplied.",
  1412. X"",
  1413. X"    Options and other command line arguments may be mixed",
  1414. X"    arbitrarily on the command line, after the function",
  1415. X"    selectors.",
  1416. X"",
  1417. X"    The GNU long option names are understood.  Since all",
  1418. X"    option names for aegis are long, this means ignoring the",
  1419. X"    extra leading '-'.  The \"--option=value\" convention is",
  1420. X"    also understood.",
  1421. X"",
  1422. X"RECOMMENDED ALIAS",
  1423. X"    The recommended alias for this command is",
  1424. X"    csh%%    alias aede '%s -de \\!* -v'",
  1425. X"    sh$    aede(){%s -de $* -v}",
  1426. X"",
  1427. X"ERRORS",
  1428. X"    It is an error if the change is not assigned to the",
  1429. X"    current user.",
  1430. X"    It is an error if The change is not in the",
  1431. X"    'being_developed' state.",
  1432. X"    It is an error if there has been no successful '%s",
  1433. X"    -Build' command since a change file was last edited.",
  1434. X"    It is an error if there has been no successful '%s",
  1435. X"    -DIFFerence' command since a change file was last edited.",
  1436. X"    It is an error if there has been no successful '%s",
  1437. X"    -Test' command since a change file was last edited.",
  1438. X"    It is an error if there has been no successful '%s",
  1439. X"    -Test -BaseLine' command since a change file was last",
  1440. X"    edited.",
  1441. X"",
  1442. X"EXIT STATUS",
  1443. X"    The %s command will exit with a status of 1 on any",
  1444. X"    error.    The %s command will only exit with a status of",
  1445. X"    0 if there are no errors.",
  1446. X"",
  1447. X"COPYRIGHT",
  1448. X"    %C",
  1449. X"",
  1450. X"AUTHOR",
  1451. X"    %A",
  1452. X    };
  1453. X
  1454. X    help(text, SIZEOF(text), develop_end_usage);
  1455. X}
  1456. X
  1457. X
  1458. Xstatic void develop_end_list _((void));
  1459. X
  1460. Xstatic void
  1461. Xdevelop_end_list()
  1462. X{
  1463. X    string_ty    *project_name;
  1464. X
  1465. X    trace(("develop_end_list()\n{\n"/*}*/));
  1466. X    project_name = 0;
  1467. X    arglex();
  1468. X    while (arglex_token != arglex_token_eoln)
  1469. X    {
  1470. X        switch (arglex_token)
  1471. X        {
  1472. X        default:
  1473. X            generic_argument(develop_end_usage);
  1474. X            continue;
  1475. X
  1476. X        case arglex_token_project:
  1477. X            if (arglex() != arglex_token_string)
  1478. X                develop_end_usage();
  1479. X            /* fall through... */
  1480. X        
  1481. X        case arglex_token_string:
  1482. X            if (project_name)
  1483. X                fatal("duplicate -Project option");
  1484. X            project_name = str_from_c(arglex_value.alv_string);
  1485. X            break;
  1486. X        }
  1487. X        arglex();
  1488. X    }
  1489. X    list_changes_in_state_mask
  1490. X    (
  1491. X        project_name,
  1492. X        1 << cstate_state_being_developed
  1493. X    );
  1494. X    if (project_name)
  1495. X        str_free(project_name);
  1496. X    trace((/*{*/"}\n"));
  1497. X}
  1498. X
  1499. X
  1500. Xstatic void repair_diff_time _((change_ty *, string_ty *));
  1501. X
  1502. Xstatic void
  1503. Xrepair_diff_time(cp, path)
  1504. X    change_ty    *cp;
  1505. X    string_ty    *path;
  1506. X{
  1507. X    string_ty    *s;
  1508. X    cstate_src    src_data;
  1509. X    string_ty    *s2;
  1510. X
  1511. X    s = os_below_dir(change_development_directory_get(cp, 1), path);
  1512. X    src_data = change_src_find(cp, s);
  1513. X    if (src_data)
  1514. X        src_data->diff_time = os_mtime(path);
  1515. X    else
  1516. X    {
  1517. X        if
  1518. X        (
  1519. X            s->str_length > 2
  1520. X        &&
  1521. X            !strcmp(s->str_text + s->str_length - 2, ",D")
  1522. X        )
  1523. X        {
  1524. X            s2 = str_n_from_c(s->str_text, s->str_length - 2);
  1525. X            src_data = change_src_find(cp, s2);
  1526. X            if (src_data)
  1527. X                src_data->diff_file_time = os_mtime(path);
  1528. X            str_free(s2);
  1529. X        }
  1530. X    }
  1531. X    str_free(s);
  1532. X}
  1533. X
  1534. X
  1535. Xstatic void de_func _((void *, dir_walk_message_ty, string_ty *, struct stat *));
  1536. X
  1537. Xstatic void
  1538. Xde_func(arg, message, path, st)
  1539. X    void        *arg;
  1540. X    dir_walk_message_ty message;
  1541. X    string_ty    *path;
  1542. X    struct stat    *st;
  1543. X{
  1544. X    change_ty    *cp;
  1545. X    int        uid;
  1546. X
  1547. X    trace(("de_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  1548. X        message, path->str_text, st));
  1549. X    cp = (change_ty *)arg;
  1550. X    switch (message)
  1551. X    {
  1552. X    case dir_walk_file:
  1553. X    case dir_walk_dir_after:
  1554. X        os_become_query(&uid, (int *)0, (int *)0);
  1555. X        if (st->st_uid == uid)
  1556. X        {
  1557. X            os_chmod(path, st->st_mode & 07555);
  1558. X            undo_chmod(path, st->st_mode);
  1559. X        }
  1560. X        repair_diff_time(cp, path);
  1561. X        break;
  1562. X
  1563. X    case dir_walk_special:
  1564. X    case dir_walk_symlink:
  1565. X    case dir_walk_dir_before:
  1566. X        break;
  1567. X    }
  1568. X    trace((/*{*/"}\n"));
  1569. X}
  1570. X
  1571. X
  1572. Xstatic void develop_end_main _((void));
  1573. X
  1574. Xstatic void
  1575. Xdevelop_end_main()
  1576. X{
  1577. X    string_ty    *dd;
  1578. X    cstate        cstate_data;
  1579. X    pstate        pstate_data;
  1580. X    int        j;
  1581. X    cstate_history    history_data;
  1582. X    string_ty    *project_name;
  1583. X    project_ty    *pp;
  1584. X    long        change_number;
  1585. X    change_ty    *cp;
  1586. X    user_ty        *up;
  1587. X    int        build_whine;
  1588. X    int        test_whine;
  1589. X    int        test_bl_whine;
  1590. X    int        reg_test_whine;
  1591. X    int        diff_whine;
  1592. X    int        errs;
  1593. X
  1594. X    trace(("develop_end_main()\n{\n"/*}*/));
  1595. X    project_name = 0;
  1596. X    change_number = 0;
  1597. X    while (arglex_token != arglex_token_eoln)
  1598. X    {
  1599. X        switch (arglex_token)
  1600. X        {
  1601. X        default:
  1602. X            generic_argument(develop_end_usage);
  1603. X            continue;
  1604. X
  1605. X        case arglex_token_change:
  1606. X            if (arglex() != arglex_token_number)
  1607. X                develop_end_usage();
  1608. X            /* fall through... */
  1609. X
  1610. X        case arglex_token_number:
  1611. X            if (change_number)
  1612. X                fatal("duplicate -Change option");
  1613. X            change_number = arglex_value.alv_number;
  1614. X            if (change_number < 1)
  1615. X                fatal("change %ld out of range", change_number);
  1616. X            break;
  1617. X
  1618. X        case arglex_token_project:
  1619. X            if (arglex() != arglex_token_string)
  1620. X                develop_end_usage();
  1621. X            /* fall through... */
  1622. X        
  1623. X        case arglex_token_string:
  1624. X            if (project_name)
  1625. X                fatal("duplicate -Project option");
  1626. X            project_name = str_from_c(arglex_value.alv_string);
  1627. X            break;
  1628. X        }
  1629. X        arglex();
  1630. X    }
  1631. X
  1632. X    /*
  1633. X     * locate project data
  1634. X     */
  1635. X    if (!project_name)
  1636. X        project_name = user_default_project();
  1637. X    pp = project_alloc(project_name);
  1638. X    str_free(project_name);
  1639. X    project_bind_existing(pp);
  1640. X
  1641. X    /*
  1642. X     * locate user data
  1643. X     */
  1644. X    up = user_executing(pp);
  1645. X
  1646. X    /*
  1647. X     * locate change data
  1648. X     */
  1649. X    if (!change_number)
  1650. X        change_number = user_default_change(up);
  1651. X    cp = change_alloc(pp, change_number);
  1652. X    change_bind_existing(cp);
  1653. X
  1654. X    /*
  1655. X     * Take an advisory write lock on the appropriate row of the change
  1656. X     * table.  Take an advisory write lock on the appropriate row of the
  1657. X     * user table.  Block until can get both simultaneously.
  1658. X     */
  1659. X    project_pstate_lock_prepare(pp);
  1660. X    change_cstate_lock_prepare(cp);
  1661. X    user_ustate_lock_prepare(up);
  1662. X    lock_take();
  1663. X    cstate_data = change_cstate_get(cp);
  1664. X    pstate_data = project_pstate_get(pp);
  1665. X
  1666. X    /*
  1667. X     * It is an error if the change is not in the in-development state.
  1668. X     * It is an error if the change is not assigned to the current user.
  1669. X     * It is an error if the change has no current diff.
  1670. X     * It is an error if the change has no current build.
  1671. X     * It is an error if the change has no current test pass.
  1672. X     * It is an error if the change has no current baseline test pass.
  1673. X     * It is an error if the change has no new test associtaed with it.
  1674. X     */
  1675. X    if (cstate_data->state != cstate_state_being_developed)
  1676. X        change_fatal(cp, "not in 'being_developed' state");
  1677. X    if (!str_equal(change_developer_name(cp), user_name(up)))
  1678. X    {
  1679. X        change_fatal
  1680. X        (
  1681. X            cp,
  1682. X            "user \"%S\" is not the developer",
  1683. X            user_name(up)
  1684. X        );
  1685. X    }
  1686. X    if (!cstate_data->src->length)
  1687. X        change_fatal(cp, "no files");
  1688. X    errs = 0;
  1689. X    build_whine = 0;
  1690. X    test_whine = 0;
  1691. X    test_bl_whine = 0;
  1692. X    reg_test_whine = 0;
  1693. X    diff_whine = 0;
  1694. X
  1695. X    /*
  1696. X     * It is an error if any files in the change file table have been
  1697. X     * modified since the last build.
  1698. X     * It is an error if any files in the change file table have been
  1699. X     * modified since the last diff.
  1700. X     */
  1701. X    dd = change_development_directory_get(cp, 1);
  1702. X    user_become(up);
  1703. X    for (j = 0; j < cstate_data->src->length; ++j)
  1704. X    {
  1705. X        cstate_src    c_src_data;
  1706. X        pstate_src    p_src_data;
  1707. X        string_ty    *path;
  1708. X        string_ty    *path_d;
  1709. X        long        when;
  1710. X        long        when_d;
  1711. X        int        file_required;
  1712. X        int        diff_file_required;
  1713. X
  1714. X        file_required = 1;
  1715. X        diff_file_required = 1;
  1716. X        c_src_data = cstate_data->src->list[j];
  1717. X        if (c_src_data->action == file_action_remove)
  1718. X            file_required = 0;
  1719. X        if (c_src_data->usage == file_usage_build)
  1720. X        {
  1721. X            file_required = 0;
  1722. X            diff_file_required = 0;
  1723. X        }
  1724. X
  1725. X        /*
  1726. X         * make sure the file exists
  1727. X         */
  1728. X        path = str_format("%S/%S", dd, c_src_data->file_name);
  1729. X        if (os_exists(path))
  1730. X            when = os_mtime(path);
  1731. X        else
  1732. X            when = 0;
  1733. X        if (file_required && !when)
  1734. X        {
  1735. X            change_error
  1736. X            (
  1737. X                cp,
  1738. X                "file \"%s\" not found",
  1739. X                c_src_data->file_name->str_text
  1740. X            );
  1741. X            str_free(path);
  1742. X            errs++;
  1743. X            continue;
  1744. X        }
  1745. X
  1746. X        /*
  1747. X         * get the difference time
  1748. X         */
  1749. X        path_d = str_format("%S,D", path);
  1750. X        str_free(path);
  1751. X        if (os_exists(path_d))
  1752. X            when_d = os_mtime(path_d);
  1753. X        else
  1754. X            when_d = 0;
  1755. X        str_free(path_d);
  1756. X
  1757. X        if
  1758. X        (
  1759. X            file_required
  1760. X        &&
  1761. X            (
  1762. X                when >= cstate_data->build_time
  1763. X            ||
  1764. X                !cstate_data->build_time
  1765. X            )
  1766. X        )
  1767. X        {
  1768. X            if (!build_whine)
  1769. X            change_error
  1770. X            (
  1771. X                cp,
  1772. X                "no current '%s -Build' registration",
  1773. X                option_progname_get()
  1774. X            );
  1775. X            build_whine++;
  1776. X            errs++;
  1777. X        }
  1778. X        if
  1779. X        (
  1780. X            (
  1781. X                file_required
  1782. X            &&
  1783. X                (
  1784. X                    when != c_src_data->diff_time
  1785. X                ||
  1786. X                    !c_src_data->diff_time
  1787. X                )
  1788. X            )
  1789. X        ||
  1790. X            (
  1791. X                diff_file_required
  1792. X            &&
  1793. X                (
  1794. X                    when_d != c_src_data->diff_file_time
  1795. X                ||
  1796. X                    !c_src_data->diff_file_time
  1797. X                )
  1798. X            )
  1799. X        )
  1800. X        {
  1801. X            if (!diff_whine)
  1802. X            change_error
  1803. X            (
  1804. X                cp,
  1805. X                "no current '%s -Diff' registration",
  1806. X                option_progname_get()
  1807. X            );
  1808. X            diff_whine++;
  1809. X            errs++;
  1810. X        }
  1811. X        if
  1812. X        (
  1813. X            !cstate_data->test_exempt
  1814. X        &&
  1815. X            file_required
  1816. X        &&
  1817. X            (
  1818. X                when >= cstate_data->test_time
  1819. X            ||
  1820. X                !cstate_data->test_time
  1821. X            )
  1822. X        )
  1823. X        {
  1824. X            if (!test_whine)
  1825. X            change_error
  1826. X            (
  1827. X                cp,
  1828. X                "no current '%s -Test' registration",
  1829. X                option_progname_get()
  1830. X            );
  1831. X            test_whine++;
  1832. X            errs++;
  1833. X        }
  1834. X        if
  1835. X        (
  1836. X            !cstate_data->test_baseline_exempt
  1837. X        &&
  1838. X            file_required
  1839. X        &&
  1840. X            (
  1841. X                when >= cstate_data->test_baseline_time
  1842. X            ||
  1843. X                !cstate_data->test_baseline_time
  1844. X            )
  1845. X        )
  1846. X        {
  1847. X            if (!test_bl_whine)
  1848. X            change_error
  1849. X            (
  1850. X                cp,
  1851. X                "no current '%s -Test -BaseLine' registration",
  1852. X                option_progname_get()
  1853. X            );
  1854. X            test_bl_whine++;
  1855. X            errs++;
  1856. X        }
  1857. X        if
  1858. X        (
  1859. X            !cstate_data->regression_test_exempt
  1860. X        &&
  1861. X            file_required
  1862. X        &&
  1863. X            (
  1864. X                when >= cstate_data->regression_test_time
  1865. X            ||
  1866. X                !cstate_data->regression_test_time
  1867. X            )
  1868. X        )
  1869. X        {
  1870. X            if (!reg_test_whine)
  1871. X            change_error
  1872. X            (
  1873. X                cp,
  1874. X                   "no current '%s -Test -REGression' registration",
  1875. X                option_progname_get()
  1876. X            );
  1877. X            reg_test_whine++;
  1878. X            errs++;
  1879. X        }
  1880. X
  1881. X        /*
  1882. X         * It is an error if any files in the change file table haved
  1883. X         * different edit numbers to the baseline file table edit
  1884. X         * numbers.
  1885. X         */
  1886. X        if (c_src_data->action != file_action_create)
  1887. X        {
  1888. X            p_src_data = project_src_find(pp, c_src_data->file_name);
  1889. X            if (!p_src_data)
  1890. X            {
  1891. X                change_error
  1892. X                (
  1893. X                    cp,
  1894. X                    "file \"%S\" no longer in baseline",
  1895. X                    c_src_data->file_name
  1896. X                );
  1897. X                errs++;
  1898. X            }
  1899. X            if
  1900. X            (
  1901. X                !str_equal
  1902. X                (
  1903. X                    c_src_data->edit_number,
  1904. X                    p_src_data->edit_number
  1905. X                )
  1906. X            )
  1907. X            {
  1908. X                change_error
  1909. X                (
  1910. X                    cp,
  1911. X      "file \"%S\" in baseline has changed since last '%s -DIFFerence' command",
  1912. X                    c_src_data->file_name,
  1913. X                    option_progname_get()
  1914. X                );
  1915. X                errs++;
  1916. X            }
  1917. X
  1918. X            /*
  1919. X             * make sure we can lock the file
  1920. X             */
  1921. X            if (p_src_data->locked_by)
  1922. X            {
  1923. X                change_error
  1924. X                (
  1925. X                    cp,
  1926. X                    "file \"%S\" locked for change %d",
  1927. X                    c_src_data->file_name,
  1928. X                    p_src_data->locked_by
  1929. X                );
  1930. X                errs++;
  1931. X            }
  1932. X        }
  1933. X        else
  1934. X        {
  1935. X            /*
  1936. X             * add a new entry to the pstate src list,
  1937. X             * and mark it as "about to be created".
  1938. X             */
  1939. X            p_src_data = project_src_new(pp, c_src_data->file_name);
  1940. X            p_src_data->usage = c_src_data->usage;
  1941. X            p_src_data->about_to_be_created_by = change_number;
  1942. X        }
  1943. X        p_src_data->locked_by = change_number;
  1944. X    }
  1945. X    if (errs)
  1946. X        quit(1);
  1947. X
  1948. X    /*
  1949. X     * Change all of the files in the development directory
  1950. X     * to be read-only, and record the new ctime.
  1951. X     */
  1952. X    dir_walk(dd, de_func, cp);
  1953. X    user_become_undo();
  1954. X
  1955. X    /*
  1956. X     * add to history for state change
  1957. X     */
  1958. X    history_data = change_history_new(cp, up);
  1959. X    history_data->what = cstate_history_what_develop_end;
  1960. X
  1961. X    /*
  1962. X     * Advance the change to the being-reviewed state.
  1963. X     * Clear the build-time field.
  1964. X     * Clear the test-time field.
  1965. X     * Clear the test-baseline-time field.
  1966. X     */
  1967. X    cstate_data->state = cstate_state_being_reviewed;
  1968. X    cstate_data->build_time = 0;
  1969. X    cstate_data->test_time = 0;
  1970. X    cstate_data->test_baseline_time = 0;
  1971. X    cstate_data->regression_test_time = 0;
  1972. X
  1973. X    /*
  1974. X     * Remove the change from the list of assigned changes in the user
  1975. X     * change table (in the user row).
  1976. X     */
  1977. X    user_own_remove(up, project_name_get(pp), change_number);
  1978. X
  1979. X    /*
  1980. X     * Write the change table row.
  1981. X     * Write the user table row.
  1982. X     * Release advisory locks.
  1983. X     */
  1984. X    change_cstate_write(cp);
  1985. X    project_pstate_write(pp);
  1986. X    user_ustate_write(up);
  1987. X    commit();
  1988. X    lock_release();
  1989. X
  1990. X    /*
  1991. X     * run the notify command
  1992. X     */
  1993. X    change_run_develop_end_notify_command(cp);
  1994. X
  1995. X    /*
  1996. X     * verbose success message
  1997. X     */
  1998. X    change_verbose(cp, "development completed");
  1999. X    change_free(cp);
  2000. X    project_free(pp);
  2001. X    user_free(up);
  2002. X    trace((/*{*/"}\n"));
  2003. X}
  2004. X
  2005. X
  2006. Xvoid
  2007. Xdevelop_end()
  2008. X{
  2009. X    trace(("develop_end()\n{\n"/*}*/));
  2010. X    switch (arglex())
  2011. X    {
  2012. X    default:
  2013. X        develop_end_main();
  2014. X        break;
  2015. X
  2016. X    case arglex_token_help:
  2017. X        develop_end_help();
  2018. X        break;
  2019. X
  2020. X    case arglex_token_list:
  2021. X        develop_end_list();
  2022. X        break;
  2023. X    }
  2024. X    trace((/*{*/"}\n"));
  2025. X}
  2026. END_OF_FILE
  2027. if test 17211 -ne `wc -c <'aegis/aede.c'`; then
  2028.     echo shar: \"'aegis/aede.c'\" unpacked with wrong size!
  2029. fi
  2030. # end of 'aegis/aede.c'
  2031. fi
  2032. if test -f 'aegis/aeif.c' -a "${1}" != "-c" ; then 
  2033.   echo shar: Will not clobber existing file \"'aegis/aeif.c'\"
  2034. else
  2035. echo shar: Extracting \"'aegis/aeif.c'\" \(14342 characters\)
  2036. sed "s/^X//" >'aegis/aeif.c' <<'END_OF_FILE'
  2037. X/*
  2038. X *    aegis - project change supervisor
  2039. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  2040. X *    All rights reserved.
  2041. X *
  2042. X *    This program is free software; you can redistribute it and/or modify
  2043. X *    it under the terms of the GNU General Public License as published by
  2044. X *    the Free Software Foundation; either version 2 of the License, or
  2045. X *    (at your option) any later version.
  2046. X *
  2047. X *    This program is distributed in the hope that it will be useful,
  2048. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2049. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2050. X *    GNU General Public License for more details.
  2051. X *
  2052. X *    You should have received a copy of the GNU General Public License
  2053. X *    along with this program; if not, write to the Free Software
  2054. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2055. X *
  2056. X * MANIFEST: functions for implementing integrate fail
  2057. X */
  2058. X
  2059. X#include <stdio.h>
  2060. X#include <stdlib.h>
  2061. X#include <string.h>
  2062. X#include <sys/types.h>
  2063. X#include <sys/stat.h>
  2064. X
  2065. X#include <aeif.h>
  2066. X#include <ael.h>
  2067. X#include <arglex2.h>
  2068. X#include <commit.h>
  2069. X#include <change.h>
  2070. X#include <dir.h>
  2071. X#include <error.h>
  2072. X#include <file.h>
  2073. X#include <help.h>
  2074. X#include <lock.h>
  2075. X#include <log.h>
  2076. X#include <option.h>
  2077. X#include <os.h>
  2078. X#include <project.h>
  2079. X#include <sub.h>
  2080. X#include <trace.h>
  2081. X#include <undo.h>
  2082. X#include <user.h>
  2083. X
  2084. X
  2085. Xstatic void integrate_fail_usage _((void));
  2086. X
  2087. Xstatic void
  2088. Xintegrate_fail_usage()
  2089. X{
  2090. X    char        *progname;
  2091. X
  2092. X    progname = option_progname_get();
  2093. X    fprintf(stderr, "usage: %s -Integrate_FAIL <reason-file> [ <option>... ]\n", progname);
  2094. X    fprintf(stderr, "       %s -Integrate_FAIL -Edit [ <option>... ]\n", progname);
  2095. X    fprintf(stderr, "       %s -Integrate_FAIL -List [ <option>... ]\n", progname);
  2096. X    fprintf(stderr, "       %s -Integrate_FAIL -Help\n", progname);
  2097. X    quit(1);
  2098. X}
  2099. X
  2100. X
  2101. Xstatic void integrate_fail_help _((void));
  2102. X
  2103. Xstatic void
  2104. Xintegrate_fail_help()
  2105. X{
  2106. X    static char *text[] =
  2107. X    {
  2108. X"NAME",
  2109. X"    %s -Integrate_FAIL - fail a change integration",
  2110. X"",
  2111. X"SYNOPSIS",
  2112. X"    %s -Integrate_FAIL <reason-file> [ <option>... ]",
  2113. X"    %s -Integrate_FAIL -Edit [ <option>... ]",
  2114. X"    %s -Integrate_FAIL -List [ <option>... ]",
  2115. X"    %s -Integrate_FAIL -Help",
  2116. X"",
  2117. X"DESCRIPTION",
  2118. X"    The %s -Integrate_FAIL command is used to inform %s",
  2119. X"    that a change has failed integration.",
  2120. X"",
  2121. X"    The change will be returned from the 'being_integrated'",
  2122. X"    state to the 'being_developed' state.  The change will",
  2123. X"    cease to be assigned to the current user, and will be",
  2124. X"    reassigned to the originating developer.  The integration",
  2125. X"    directory will be deleted.",
  2126. X"",
  2127. X"    The reviewer and the developer will be notified by mail.",
  2128. X"    See the integrate_fail_notify_command in aepconf(5) for",
  2129. X"    more information.",
  2130. X"",
  2131. X"OPTIONS",
  2132. X"    The following options are understood:",
  2133. X"",
  2134. X"    -Change <number>",
  2135. X"        This option may be used to specify a particular",
  2136. X"        change within a project.  When no -Change option is",
  2137. X"        specified, the AEGIS_CHANGE environment variable is",
  2138. X"        consulted.  If that does not exist, the user's",
  2139. X"        $HOME/.aegisrc file is examined for a default change",
  2140. X"        field (see aeuconf(5) for more information).  If",
  2141. X"        that does not exist, when the user is only working",
  2142. X"        on one change within a project, that is the default",
  2143. X"        change number.  Otherwise, it is an error.",
  2144. X"",
  2145. X"    -Edit",
  2146. X"        Edit the attributes with a text editor, this is",
  2147. X"        usually more convenient than supplying a text",
  2148. X"        file.  The EDITOR environment variable will be",
  2149. X"        consulted for the name of the editor to use;",
  2150. X"        defaults to vi(1) if not set.  Warning: not well",
  2151. X"        behaved when faced with errors, the temporary",
  2152. X"        file is always deleted.",
  2153. X"",
  2154. X"    -Help",
  2155. X"        This option may be used to obtain more",
  2156. X"        information about how to use the %s program.",
  2157. X"",
  2158. X"    -Keep",
  2159. X"        This option may be used to retain files and/or",
  2160. X"        directories usually deleted by the command.",
  2161. X"",
  2162. X"    -List",
  2163. X"        This option may be used to obtain a list of",
  2164. X"        suitable subjects for this command.  The list may",
  2165. X"        be more general than expected.",
  2166. X"",
  2167. X"    -Project <name>",
  2168. X"        This option may be used to select the project of",
  2169. X"        interest.  When no -Project option is specified, the",
  2170. X"        AEGIS_PROJECT environment variable is consulted.  If",
  2171. X"        that does not exist, the user's $HOME/.aegisrc file",
  2172. X"        is examined for a default project field (see",
  2173. X"        aeuconf(5) for more information).  If that does not",
  2174. X"        exist, when the user is only working on changes",
  2175. X"        within a single project, the project name defaults",
  2176. X"        to that project.  Otherwise, it is an error.",
  2177. X"",
  2178. X"    -TERse",
  2179. X"        This option may be used to cause listings to",
  2180. X"        produce the bare minimum of information.  It is",
  2181. X"        usually useful for shell scripts.",
  2182. X"",
  2183. X"    -Verbose",
  2184. X"        This option may be used to cause %s to produce",
  2185. X"        more output.  By default %s only produces",
  2186. X"        output on errors.  When used with the -List",
  2187. X"        option this option causes column headings to be",
  2188. X"        added.",
  2189. X"",
  2190. X"    All options may be abbreviated; the abbreviation is",
  2191. X"    documented as the upper case letters, all lower case",
  2192. X"    letters and underscores (_) are optional.  You must use",
  2193. X"    consecutive sequences of optional letters.",
  2194. X"",
  2195. X"    All options are case insensitive, you may type them in",
  2196. X"    upper case or lower case or a combination of both, case",
  2197. X"    is not important.",
  2198. X"",
  2199. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  2200. X"    are all interpreted to mean the -Project option.  The",
  2201. X"    argument \"-prj\" will not be understood, because",
  2202. X"    consecutive optional characters were not supplied.",
  2203. X"",
  2204. X"    Options and other command line arguments may be mixed",
  2205. X"    arbitrarily on the command line, after the function",
  2206. X"    selectors.",
  2207. X"",
  2208. X"    The GNU long option names are understood.  Since all",
  2209. X"    option names for aegis are long, this means ignoring the",
  2210. X"    extra leading '-'.  The \"--option=value\" convention is",
  2211. X"    also understood.",
  2212. X"",
  2213. X"RECOMMENDED ALIAS",
  2214. X"    The recommended alias for this command is",
  2215. X"    csh%%    alias aeif '%s -if \\!* -v'",
  2216. X"    sh$    aeif(){%s -if $* -v}",
  2217. X"",
  2218. X"ERRORS",
  2219. X"    It is an error if the change is not in the",
  2220. X"    'being_integrated' state.",
  2221. X"    It is an error if the change is not assigned to the",
  2222. X"    current user.",
  2223. X"",
  2224. X"EXIT STATUS",
  2225. X"    The %s command will exit with a status of 1 on any",
  2226. X"    error.    The %s command will only exit with a status of",
  2227. X"    0 if there are no errors.",
  2228. X"",
  2229. X"COPYRIGHT",
  2230. X"    %C",
  2231. X"",
  2232. X"AUTHOR",
  2233. X"    %A",
  2234. X    };
  2235. X
  2236. X    help(text, SIZEOF(text), integrate_fail_usage);
  2237. X}
  2238. X
  2239. X
  2240. Xstatic void integrate_fail_list _((void (*)(void)));
  2241. X
  2242. Xstatic void
  2243. Xintegrate_fail_list(usage)
  2244. X    void        (*usage)_((void));
  2245. X{
  2246. X    string_ty    *project_name;
  2247. X
  2248. X    trace(("integrate_fail_list()\n{\n"/*}*/));
  2249. X    arglex();
  2250. X    project_name = 0;
  2251. X    while (arglex_token != arglex_token_eoln)
  2252. X    {
  2253. X        switch (arglex_token)
  2254. X        {
  2255. X        default:
  2256. X            generic_argument(usage);
  2257. X            continue;
  2258. X
  2259. X        case arglex_token_project:
  2260. X            if (arglex() != arglex_token_string)
  2261. X                usage();
  2262. X            if (project_name)
  2263. X                fatal("duplicate -Project option");
  2264. X            project_name = str_from_c(arglex_value.alv_string);
  2265. X            break;
  2266. X        }
  2267. X        arglex();
  2268. X    }
  2269. X    list_changes_in_state_mask
  2270. X    (
  2271. X        project_name,
  2272. X        1 << cstate_state_being_integrated
  2273. X    );
  2274. X    if (project_name)
  2275. X        str_free(project_name);
  2276. X    trace((/*{*/"}\n"));
  2277. X}
  2278. X
  2279. X
  2280. Xstatic void repair_diff_time _((change_ty *, string_ty *));
  2281. X
  2282. Xstatic void
  2283. Xrepair_diff_time(cp, path)
  2284. X    change_ty    *cp;
  2285. X    string_ty    *path;
  2286. X{
  2287. X    string_ty    *s;
  2288. X    cstate_src    src_data;
  2289. X    string_ty    *s2;
  2290. X
  2291. X    s = os_below_dir(change_development_directory_get(cp, 1), path);
  2292. X    src_data = change_src_find(cp, s);
  2293. X    if (src_data)
  2294. X        src_data->diff_time = os_mtime(path);
  2295. X    else
  2296. X    {
  2297. X        if
  2298. X        (
  2299. X            s->str_length > 2
  2300. X        &&
  2301. X            !strcmp(s->str_text + s->str_length - 2, ",D")
  2302. X        )
  2303. X        {
  2304. X            s2 = str_n_from_c(s->str_text, s->str_length - 2);
  2305. X            src_data = change_src_find(cp, s2);
  2306. X            if (src_data)
  2307. X                src_data->diff_file_time = os_mtime(path);
  2308. X            str_free(s2);
  2309. X        }
  2310. X    }
  2311. X    str_free(s);
  2312. X}
  2313. X
  2314. X
  2315. Xstatic void if_func _((void *, dir_walk_message_ty, string_ty *, struct stat *));
  2316. X
  2317. Xstatic void
  2318. Xif_func(arg, message, path, st)
  2319. X    void        *arg;
  2320. X    dir_walk_message_ty message;
  2321. X    string_ty    *path;
  2322. X    struct stat    *st;
  2323. X{
  2324. X    change_ty    *cp;
  2325. X    int        uid;
  2326. X
  2327. X    trace(("if_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  2328. X        message, path->str_text, st));
  2329. X    cp = (change_ty *)arg;
  2330. X    switch (message)
  2331. X    {
  2332. X    case dir_walk_dir_before:
  2333. X    case dir_walk_file:
  2334. X        os_become_query(&uid, (int *)0, (int *)0);
  2335. X        if (st->st_uid == uid)
  2336. X        {
  2337. X            os_chmod
  2338. X            (
  2339. X                path,
  2340. X                (st->st_mode | 0644) & ~change_umask(cp)
  2341. X            );
  2342. X            undo_chmod(path, st->st_mode);
  2343. X            repair_diff_time(cp, path);
  2344. X        }
  2345. X        break;
  2346. X
  2347. X    case dir_walk_special:
  2348. X    case dir_walk_symlink:
  2349. X    case dir_walk_dir_after:
  2350. X        break;
  2351. X    }
  2352. X    trace((/*{*/"}\n"));
  2353. X}
  2354. X
  2355. X
  2356. Xstatic void integrate_fail_main _((void));
  2357. X
  2358. Xstatic void
  2359. Xintegrate_fail_main()
  2360. X{
  2361. X    string_ty    *dd;
  2362. X    cstate        cstate_data;
  2363. X    pstate        pstate_data;
  2364. X    cstate_history    history_data;
  2365. X    string_ty    *comment = 0;
  2366. X    string_ty    *rev_name;
  2367. X    string_ty    *int_name;
  2368. X    string_ty    *dir;
  2369. X    int        j;
  2370. X    string_ty    *project_name;
  2371. X    project_ty    *pp;
  2372. X    long        change_number;
  2373. X    change_ty    *cp;
  2374. X    user_ty        *up;
  2375. X    user_ty        *devup;
  2376. X    int        edit;
  2377. X
  2378. X    trace(("integrate_fail_main()\n{\n"/*}*/));
  2379. X    project_name = 0;
  2380. X    change_number = 0;
  2381. X    edit = 0;
  2382. X    while (arglex_token != arglex_token_eoln)
  2383. X    {
  2384. X        switch (arglex_token)
  2385. X        {
  2386. X        default:
  2387. X            generic_argument(integrate_fail_usage);
  2388. X            continue;
  2389. X
  2390. X        case arglex_token_string:
  2391. X            if (comment)
  2392. X                fatal("too many files named");
  2393. X            os_become_orig();
  2394. X            comment = read_whole_file(arglex_value.alv_string);
  2395. X            os_become_undo();
  2396. X            break;
  2397. X
  2398. X        case arglex_token_change:
  2399. X            if (arglex() != arglex_token_number)
  2400. X                integrate_fail_usage();
  2401. X            /* fall through... */
  2402. X
  2403. X        case arglex_token_number:
  2404. X            if (change_number)
  2405. X                fatal("duplicate -Change option");
  2406. X            change_number = arglex_value.alv_number;
  2407. X            if (change_number < 1)
  2408. X                fatal("change %ld out of range", change_number);
  2409. X            break;
  2410. X
  2411. X        case arglex_token_project:
  2412. X            if (arglex() != arglex_token_string)
  2413. X                integrate_fail_usage();
  2414. X            if (project_name)
  2415. X                fatal("duplicate -Project option");
  2416. X            project_name = str_from_c(arglex_value.alv_string);
  2417. X            break;
  2418. X
  2419. X        case arglex_token_edit:
  2420. X            if (edit)
  2421. X                fatal("duplicate %s option", arglex_value.alv_string);
  2422. X            ++edit;
  2423. X            break;
  2424. X        }
  2425. X        arglex();
  2426. X    }
  2427. X    if (edit)
  2428. X    {
  2429. X        if (comment)
  2430. X            fatal("may not use -Edit and also name a comment file");
  2431. X        comment = os_edit_new();
  2432. X    }
  2433. X    if (!comment)
  2434. X        fatal("no comment file supplied");
  2435. X
  2436. X    /*
  2437. X     * locate project data
  2438. X     */
  2439. X    if (!project_name)
  2440. X        project_name = user_default_project();
  2441. X    pp = project_alloc(project_name);
  2442. X    str_free(project_name);
  2443. X    project_bind_existing(pp);
  2444. X
  2445. X    /*
  2446. X     * locate user data
  2447. X     */
  2448. X    up = user_executing(pp);
  2449. X
  2450. X    /*
  2451. X     * locate change data
  2452. X     */
  2453. X    if (!change_number)
  2454. X        change_number = user_default_change(up);
  2455. X    cp = change_alloc(pp, change_number);
  2456. X    change_bind_existing(cp);
  2457. X
  2458. X    /*
  2459. X     * lock the change for writing
  2460. X     */
  2461. X    project_pstate_lock_prepare(pp);
  2462. X    change_cstate_lock_prepare(cp);
  2463. X    lock_prepare_ustate_all(); /* we don't know which users until later */
  2464. X    lock_take();
  2465. X    cstate_data = change_cstate_get(cp);
  2466. X    pstate_data = project_pstate_get(pp);
  2467. X
  2468. X    /*
  2469. X     * it is an error if the change is not in the 'being_integrated' state.
  2470. X     */
  2471. X    if (cstate_data->state != cstate_state_being_integrated)
  2472. X        change_fatal(cp, "not in 'being_integrated' state");
  2473. X    if (!str_equal(change_integrator_name(cp), user_name(up)))
  2474. X    {
  2475. X        change_fatal
  2476. X        (
  2477. X            cp,
  2478. X            "user \"%S\" not the integrator",
  2479. X            user_name(up)
  2480. X        );
  2481. X    }
  2482. X
  2483. X    /*
  2484. X     * Change the state.
  2485. X     * Add to the change's history.
  2486. X     */
  2487. X    history_data = change_history_new(cp, up);
  2488. X    history_data->what = cstate_history_what_integrate_fail;
  2489. X    history_data->why = comment;
  2490. X    cstate_data->build_time = 0;
  2491. X    cstate_data->test_time = 0;
  2492. X    cstate_data->test_baseline_time = 0;
  2493. X    cstate_data->regression_test_time = 0;
  2494. X    rev_name = change_reviewer_name(cp);
  2495. X    int_name = change_integrator_name(cp);
  2496. X    cstate_data->delta_number = 0;
  2497. X    dir = str_copy(change_integration_directory_get(cp, 1));
  2498. X    change_integration_directory_clear(cp);
  2499. X    cstate_data->state = cstate_state_being_developed;
  2500. X
  2501. X    /*
  2502. X     * Complain if they are in the integration directory,
  2503. X     * because the rmdir at the end can't then run to completion.
  2504. X     */
  2505. X    os_become_orig();
  2506. X    if (os_below_dir(dir, os_curdir()))
  2507. X        change_fatal(cp, "please leave the integration directory");
  2508. X    os_become_undo();
  2509. X
  2510. X    /*
  2511. X     * note that the project has no current integration
  2512. X     */
  2513. X    pstate_data->currently_integrating_change = 0;
  2514. X
  2515. X    /*
  2516. X     * Remove it from the integrator's change list, and
  2517. X     * add it back into the developer's change list.
  2518. X     */
  2519. X    user_own_remove(up, project_name_get(pp), change_number);
  2520. X    devup = user_symbolic(pp, change_developer_name(cp));
  2521. X    user_own_add(devup, project_name_get(pp), change_number);
  2522. X
  2523. X    /*
  2524. X     * make the change files writable again
  2525. X     */
  2526. X    change_verbose(cp, "make the development directory writable again");
  2527. X    dd = change_development_directory_get(cp, 1);
  2528. X    user_become(devup);
  2529. X    dir_walk(dd, if_func, cp);
  2530. X    user_become_undo();
  2531. X
  2532. X    /*
  2533. X     * go through the files in the change and unlock them
  2534. X     * in the baseline
  2535. X     */
  2536. X    for (j = 0; j < cstate_data->src->length; ++j)
  2537. X    {
  2538. X        cstate_src    c_src_data;
  2539. X        pstate_src    p_src_data;
  2540. X
  2541. X        c_src_data = cstate_data->src->list[j];
  2542. X        p_src_data = project_src_find(pp, c_src_data->file_name);
  2543. X        if (!p_src_data)
  2544. X            continue;
  2545. X        p_src_data->locked_by = 0;
  2546. X
  2547. X        /*
  2548. X         * Remove the file if it is about_to_be_created
  2549. X         * by the change we are rescinding.
  2550. X         */
  2551. X        if (p_src_data->about_to_be_created_by)
  2552. X        {
  2553. X            assert(p_src_data->about_to_be_created_by == change_number);
  2554. X            project_src_remove(pp, c_src_data->file_name);
  2555. X        }
  2556. X    }
  2557. X
  2558. X    /*
  2559. X     * remove the integration directory
  2560. X     */
  2561. X    change_verbose(cp, "remove the integration directory");
  2562. X    project_become(pp);
  2563. X    commit_rmdir_tree_errok(dir);
  2564. X    project_become_undo();
  2565. X
  2566. X    /*
  2567. X     * write out the data and release the locks
  2568. X     */
  2569. X    change_cstate_write(cp);
  2570. X    user_ustate_write(up);
  2571. X    user_ustate_write(devup);
  2572. X    project_pstate_write(pp);
  2573. X    str_free(dir);
  2574. X    commit();
  2575. X    lock_release();
  2576. X
  2577. X    /*
  2578. X     * run the notify command
  2579. X     */
  2580. X    change_run_integrate_fail_notify_command(cp);
  2581. X
  2582. X    /*
  2583. X     * verbose success message
  2584. X     */
  2585. X    change_verbose(cp, "failed integration, returned to developer");
  2586. X    change_free(cp);
  2587. X    project_free(pp);
  2588. X    user_free(up);
  2589. X    user_free(devup);
  2590. X    trace((/*{*/"}\n"));
  2591. X}
  2592. X
  2593. X
  2594. Xvoid
  2595. Xintegrate_fail()
  2596. X{
  2597. X    trace(("integrate_fail()\n{\n"/*}*/));
  2598. X    switch (arglex())
  2599. X    {
  2600. X    default:
  2601. X        integrate_fail_main();
  2602. X        break;
  2603. X
  2604. X    case arglex_token_help:
  2605. X        integrate_fail_help();
  2606. X        break;
  2607. X
  2608. X    case arglex_token_list:
  2609. X        integrate_fail_list(integrate_fail_usage);
  2610. X        break;
  2611. X    }
  2612. X    trace((/*{*/"}\n"));
  2613. X}
  2614. END_OF_FILE
  2615. if test 14342 -ne `wc -c <'aegis/aeif.c'`; then
  2616.     echo shar: \"'aegis/aeif.c'\" unpacked with wrong size!
  2617. fi
  2618. # end of 'aegis/aeif.c'
  2619. fi
  2620. if test -f 'aegis/aemv.c' -a "${1}" != "-c" ; then 
  2621.   echo shar: Will not clobber existing file \"'aegis/aemv.c'\"
  2622. else
  2623. echo shar: Extracting \"'aegis/aemv.c'\" \(14640 characters\)
  2624. sed "s/^X//" >'aegis/aemv.c' <<'END_OF_FILE'
  2625. X/*
  2626. X *    aegis - project change supervisor
  2627. X *    Copyright (C) 1993 Peter Miller.
  2628. X *    All rights reserved.
  2629. X *
  2630. X *    This program is free software; you can redistribute it and/or modify
  2631. X *    it under the terms of the GNU General Public License as published by
  2632. X *    the Free Software Foundation; either version 2 of the License, or
  2633. X *    (at your option) any later version.
  2634. X *
  2635. X *    This program is distributed in the hope that it will be useful,
  2636. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2637. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2638. X *    GNU General Public License for more details.
  2639. X *
  2640. X *    You should have received a copy of the GNU General Public License
  2641. X *    along with this program; if not, write to the Free Software
  2642. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2643. X *
  2644. X * MANIFEST: functions to manipulate mvs
  2645. X */
  2646. X
  2647. X#include <stdio.h>
  2648. X
  2649. X#include <ael.h>
  2650. X#include <aemv.h>
  2651. X#include <arglex2.h>
  2652. X#include <change.h>
  2653. X#include <commit.h>
  2654. X#include <error.h>
  2655. X#include <file.h>
  2656. X#include <help.h>
  2657. X#include <lock.h>
  2658. X#include <log.h>
  2659. X#include <option.h>
  2660. X#include <os.h>
  2661. X#include <project.h>
  2662. X#include <trace.h>
  2663. X#include <user.h>
  2664. X#include <word.h>
  2665. X
  2666. X
  2667. Xstatic void move_file_usage _((void));
  2668. X
  2669. Xstatic void
  2670. Xmove_file_usage()
  2671. X{
  2672. X    char        *progname;
  2673. X
  2674. X    progname = option_progname_get();
  2675. X    fprintf
  2676. X    (
  2677. X        stderr,
  2678. X          "usage: %s -MoVe_file [ <option>... ] <old-name> <new-name>...\n",
  2679. X        progname
  2680. X    );
  2681. X    fprintf
  2682. X    (
  2683. X        stderr,
  2684. X        "       %s -MoVe_file -List [ <option>... ]\n",
  2685. X        progname
  2686. X    );
  2687. X    fprintf(stderr, "       %s -MoVe_file -Help\n", progname);
  2688. X    quit(1);
  2689. X}
  2690. X
  2691. X
  2692. Xstatic void move_file_help _((void));
  2693. X
  2694. Xstatic void
  2695. Xmove_file_help()
  2696. X{
  2697. X    static char *text[] =
  2698. X    {
  2699. X"NAME",
  2700. X"    aegis -MoVe_file - copy a file into a change",
  2701. X"",
  2702. X"SYNOPSIS",
  2703. X"    aegis -MoVe_file [ <option>... ] <old-name> <new-name>",
  2704. X"    aegis -MoVe_file -List [ <option>... ]",
  2705. X"    aegis -MoVe_file -Help",
  2706. X"",
  2707. X"DESCRIPTION",
  2708. X"    The aegis -MoVe_file command is used to copy a file into",
  2709. X"    a change, while changing its name at the same time.",
  2710. X"",
  2711. X"    The aegis program will attempt to determine the project",
  2712. X"    file names from the file names given on the command line.",
  2713. X"    All file names are stored within aegis projects as",
  2714. X"    relative to the root of the baseline directory tree.  The",
  2715. X"    development directory and the integration directory are",
  2716. X"    shadows of this baseline directory, and so these relative",
  2717. X"    names apply here, too.  Files named on the command line",
  2718. X"    are first converted to absolute paths if necessary.  They",
  2719. X"    are then compared with the baseline path, the development",
  2720. X"    directory path, and the integration directory path, to",
  2721. X"    determine a baseline-relative name.  It is an error if",
  2722. X"    the file named is outside one of these directory trees.",
  2723. X"",
  2724. X"    The named files will be copied from the baseline (old-",
  2725. X"    file) into the development directory (new-file), and",
  2726. X"    added to the list of files in the change.",
  2727. X"",
  2728. X"    This command will cancel any build or test registrations,",
  2729. X"    because adding another file logically invalidates them.",
  2730. X"",
  2731. X"OPTIONS",
  2732. X"    The following options are understood:",
  2733. X"",
  2734. X"    -Change <number>",
  2735. X"        This option may be used to specify a particular",
  2736. X"        change within a project.  When no -Change option",
  2737. X"        is specified, the AEGIS_CHANGE environment",
  2738. X"        variable is consulted.  If that does not exist,",
  2739. X"        the user's $HOME/.aegisrc file is examined for a",
  2740. X"        default change field (see aeuconf(5) for more",
  2741. X"        information).  If that does not exist, when the",
  2742. X"        user is only working on one change within a",
  2743. X"        project, that is the default change number.",
  2744. X"        Otherwise, it is an error.",
  2745. X"",
  2746. X"    -Help",
  2747. X"        This option may be used to obtain more",
  2748. X"        information about how to use the aegis program.",
  2749. X"",
  2750. X"    -List",
  2751. X"        This option may be used to obtain a list of",
  2752. X"        suitable subjects for this command.  The list may",
  2753. X"        be more general than expected.",
  2754. X"",
  2755. X"    -Not_Logging",
  2756. X"        This option may be used to disable the automatic",
  2757. X"        logging of output and errors to a file.  This is",
  2758. X"        often useful when several aegis commands are",
  2759. X"        combined in a shell script.",
  2760. X"",
  2761. X"    -Project <name>",
  2762. X"        This option may be used to select the project of",
  2763. X"        interest.  When no -Project option is specified,",
  2764. X"        the AEGIS_PROJECT environment variable is",
  2765. X"        consulted.  If that does not exist, the user's",
  2766. X"        $HOME/.aegisrc file is examined for a default",
  2767. X"        project field (see aeuconf(5) for more",
  2768. X"        information).  If that does not exist, when the",
  2769. X"        user is only working on changes within a single",
  2770. X"        project, the project name defaults to that",
  2771. X"        project.  Otherwise, it is an error.",
  2772. X"",
  2773. X"    -TERse",
  2774. X"        This option may be used to cause listings to",
  2775. X"        produce the bare minimum of information.  It is",
  2776. X"        usually useful for shell scripts.",
  2777. X"",
  2778. X"    -Verbose",
  2779. X"        This option may be used to cause aegis to produce",
  2780. X"        more output.  By default aegis only produces",
  2781. X"        output on errors.  When used with the -List",
  2782. X"        option this option causes column headings to be",
  2783. X"        added.",
  2784. X"",
  2785. X"    All options may be abbreviated; the abbreviation is",
  2786. X"    documented as the upper case letters, all lower case",
  2787. X"    letters and underscores (_) are optional.  You must use",
  2788. X"    consecutive sequences of optional letters.",
  2789. X"",
  2790. X"    All options are case insensitive, you may type them in",
  2791. X"    upper case or lower case or a combination of both, case",
  2792. X"    is not important.",
  2793. X"",
  2794. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  2795. X"    are all interpreted to mean the -Project option.  The",
  2796. X"    argument \"-prj\" will not be understood, because",
  2797. X"    consecutive optional characters were not supplied.",
  2798. X"",
  2799. X"    Options and other command line arguments may be mixed",
  2800. X"    arbitrarily on the command line, after the function",
  2801. X"    selectors.",
  2802. X"",
  2803. X"    The GNU long option names are understood.  Since all",
  2804. X"    option names for aegis are long, this means ignoring the",
  2805. X"    extra leading '-'.  The \"--option=value\" convention is",
  2806. X"    also understood.",
  2807. X"",
  2808. X"",
  2809. X"RECOMMENDED ALIAS",
  2810. X"    The recommended alias for this command is",
  2811. X"    csh%%    alias aemv 'aegis -mv \\!* -v'",
  2812. X"    sh$    aemv(){aegis -mv $* -v}",
  2813. X"",
  2814. X"ERRORS",
  2815. X"    It is an error if the change is not in the being",
  2816. X"    developed state.",
  2817. X"    It is an error if the change is not assigned to the",
  2818. X"    current user.",
  2819. X"    It is an error if either file is already in the change.",
  2820. X"",
  2821. X"EXIT STATUS",
  2822. X"    The aegis command will exit with a status of 1 on any",
  2823. X"    error.  The aegis command will only exit with a status of",
  2824. X"    0 if there are no errors.",
  2825. X"",
  2826. X"COPYRIGHT",
  2827. X"    %C",
  2828. X"",
  2829. X"AUTHOR",
  2830. X"    %A",
  2831. X    };
  2832. X
  2833. X    help(text, SIZEOF(text), move_file_usage);
  2834. X}
  2835. X
  2836. X
  2837. Xstatic void move_file_list _((void));
  2838. X
  2839. Xstatic void
  2840. Xmove_file_list()
  2841. X{
  2842. X    string_ty    *project_name;
  2843. X    long        change_number;
  2844. X
  2845. X    trace(("move_file_list()\n{\n"/*}*/));
  2846. X    arglex();
  2847. X    project_name = 0;
  2848. X    change_number = 0;
  2849. X    while (arglex_token != arglex_token_eoln)
  2850. X    {
  2851. X        switch (arglex_token)
  2852. X        {
  2853. X        default:
  2854. X            generic_argument(move_file_usage);
  2855. X            continue;
  2856. X
  2857. X        case arglex_token_change:
  2858. X            if (arglex() != arglex_token_number)
  2859. X                move_file_usage();
  2860. X            /* fall through... */
  2861. X
  2862. X        case arglex_token_number:
  2863. X            if (change_number)
  2864. X                fatal("duplicate -Change option");
  2865. X            change_number = arglex_value.alv_number;
  2866. X            if (change_number < 1)
  2867. X                fatal("change %ld out of range", change_number);
  2868. X            break;
  2869. X
  2870. X        case arglex_token_project:
  2871. X            if (arglex() != arglex_token_string)
  2872. X                move_file_usage();
  2873. X            if (project_name)
  2874. X                fatal("duplicate -Project option");
  2875. X            project_name = str_from_c(arglex_value.alv_string);
  2876. X            break;
  2877. X        }
  2878. X        arglex();
  2879. X    }
  2880. X    list_project_files(project_name, change_number);
  2881. X    if (project_name)
  2882. X        str_free(project_name);
  2883. X    trace((/*{*/"}\n"));
  2884. X}
  2885. X
  2886. X
  2887. Xstatic void move_file_main _((void));
  2888. X
  2889. Xstatic void
  2890. Xmove_file_main()
  2891. X{
  2892. X    string_ty    *dd;
  2893. X    string_ty    *bl;
  2894. X    string_ty    *old_name;
  2895. X    string_ty    *new_name;
  2896. X    string_ty    *s1;
  2897. X    string_ty    *s2;
  2898. X    cstate        cstate_data;
  2899. X    pstate        pstate_data;
  2900. X    wlist        wl;
  2901. X    pconf        pconf_data;
  2902. X    string_ty    *project_name;
  2903. X    project_ty    *pp;
  2904. X    long        change_number;
  2905. X    change_ty    *cp;
  2906. X    int        nolog;
  2907. X    user_ty        *up;
  2908. X    string_ty    *config_name;
  2909. X    string_ty    *from;
  2910. X    string_ty    *to;
  2911. X    cstate_src    c_src_data;
  2912. X    pstate_src    p_src_data;
  2913. X
  2914. X    trace(("move_file_main()\n{\n"/*}*/));
  2915. X    old_name = 0;
  2916. X    new_name = 0;
  2917. X    project_name = 0;
  2918. X    change_number = 0;
  2919. X    nolog = 0;
  2920. X    while (arglex_token != arglex_token_eoln)
  2921. X    {
  2922. X        switch (arglex_token)
  2923. X        {
  2924. X        default:
  2925. X            generic_argument(move_file_usage);
  2926. X            continue;
  2927. X
  2928. X        case arglex_token_string:
  2929. X            s1 = str_from_c(arglex_value.alv_string);
  2930. X            os_become_orig();
  2931. X            s2 = os_pathname(s1, 1);
  2932. X            os_become_undo();
  2933. X            str_free(s1);
  2934. X            if (!old_name)
  2935. X                old_name = s2;
  2936. X            else if (!new_name)
  2937. X                new_name = s2;
  2938. X            else
  2939. X                fatal("too many file names");
  2940. X            break;
  2941. X
  2942. X        case arglex_token_change:
  2943. X            if (arglex() != arglex_token_number)
  2944. X                move_file_usage();
  2945. X            /* fall through... */
  2946. X
  2947. X        case arglex_token_number:
  2948. X            if (change_number)
  2949. X                fatal("duplicate -Change option");
  2950. X            change_number = arglex_value.alv_number;
  2951. X            if (change_number < 1)
  2952. X                fatal("change %ld out of range", change_number);
  2953. X            break;
  2954. X
  2955. X        case arglex_token_project:
  2956. X            if (project_name)
  2957. X                goto duplicate;
  2958. X            if (arglex() != arglex_token_string)
  2959. X                move_file_usage();
  2960. X            project_name = str_from_c(arglex_value.alv_string);
  2961. X            break;
  2962. X
  2963. X        case arglex_token_nolog:
  2964. X            if (nolog)
  2965. X            {
  2966. X                duplicate:
  2967. X                fatal
  2968. X                (
  2969. X                    "duplicate %s option",
  2970. X                    arglex_value.alv_string
  2971. X                );
  2972. X            }
  2973. X            nolog = 1;
  2974. X            break;
  2975. X        }
  2976. X        arglex();
  2977. X    }
  2978. X    if (!old_name || !new_name)
  2979. X        move_file_usage();
  2980. X
  2981. X    /*
  2982. X     * locate project data
  2983. X     */
  2984. X    if (!project_name)
  2985. X        project_name = user_default_project();
  2986. X    pp = project_alloc(project_name);
  2987. X    str_free(project_name);
  2988. X    project_bind_existing(pp);
  2989. X
  2990. X    /*
  2991. X     * locate user data
  2992. X     */
  2993. X    up = user_executing(pp);
  2994. X
  2995. X    /*
  2996. X     * locate change data
  2997. X     */
  2998. X    if (!change_number)
  2999. X        change_number = user_default_change(up);
  3000. X    cp = change_alloc(pp, change_number);
  3001. X    change_bind_existing(cp);
  3002. X
  3003. X    /*
  3004. X     * lock the change file
  3005. X     */
  3006. X    change_cstate_lock_prepare(cp);
  3007. X    lock_take();
  3008. X    cstate_data = change_cstate_get(cp);
  3009. X    pstate_data = project_pstate_get(pp);
  3010. X    pconf_data = change_pconf_get(cp);
  3011. X
  3012. X    /*
  3013. X     * It is an error if the change is not in the in_development state.
  3014. X     * It is an error if the change is not assigned to the current user.
  3015. X     */
  3016. X    if (cstate_data->state != cstate_state_being_developed)
  3017. X        change_fatal(cp, "not in 'being_developed' state");
  3018. X    if (!str_equal(change_developer_name(cp), user_name(up)))
  3019. X    {
  3020. X        change_fatal
  3021. X        (
  3022. X            cp,
  3023. X            "user \"%S\" is not the developer",
  3024. X            user_name(up)
  3025. X        );
  3026. X    }
  3027. X
  3028. X    /*
  3029. X     * resolve the path of each file
  3030. X     * 1. the absolute path of the file name is obtained
  3031. X     * 2. if the file is inside the development directory, ok
  3032. X     * 3. if the file is inside the baseline, ok
  3033. X     * 4. if neither, error
  3034. X     *
  3035. X     * To cope with automounters, directories are stored as given,
  3036. X     * or are derived from the home directory in the passwd file.
  3037. X     * Within aegis, pathnames have their symbolic links resolved,
  3038. X     * and any comparison of paths is done on this "system idea"
  3039. X     * of the pathname.
  3040. X     */
  3041. X    config_name = str_from_c(THE_CONFIG_FILE);
  3042. X    if
  3043. X    (
  3044. X        str_equal(old_name, config_name)
  3045. X    ||
  3046. X        str_equal(new_name, config_name)
  3047. X    )
  3048. X        fatal("may not rename the \"%s\" file", THE_CONFIG_FILE);
  3049. X    str_free(config_name);
  3050. X
  3051. X    dd = change_development_directory_get(cp, 1);
  3052. X    bl = project_baseline_path_get(pp, 1);
  3053. X
  3054. X    os_become_orig();
  3055. X    assert(old_name->str_text[0] == '/');
  3056. X    s2 = os_below_dir(dd, old_name);
  3057. X    if (!s2)
  3058. X        s2 = os_below_dir(bl, old_name);
  3059. X    if (!s2)
  3060. X        change_fatal(cp, "path \"%S\" unrelated", old_name);
  3061. X    str_free(old_name);
  3062. X    old_name = s2;
  3063. X
  3064. X    assert(new_name->str_text[0] == '/');
  3065. X    s2 = os_below_dir(dd, new_name);
  3066. X    if (!s2)
  3067. X        s2 = os_below_dir(bl, new_name);
  3068. X    if (!s2)
  3069. X        change_fatal(cp, "path \"%S\" unrelated", new_name);
  3070. X    str_free(new_name);
  3071. X    new_name = s2;
  3072. X    os_become_undo();
  3073. X
  3074. X    /*
  3075. X     * ensure that the old file
  3076. X     * 1. is not already part of the change
  3077. X     * 2. is in the baseline
  3078. X     * 3. is not a test
  3079. X     */
  3080. X    if (change_src_find(cp, old_name))
  3081. X        change_fatal(cp, "file \"%S\" already in change", old_name);
  3082. X    p_src_data = project_src_find(pp, old_name);
  3083. X    if
  3084. X    (
  3085. X        !p_src_data
  3086. X    ||
  3087. X        p_src_data->about_to_be_created_by
  3088. X    ||
  3089. X        p_src_data->deleted_by
  3090. X    )
  3091. X        project_fatal(pp, "file \"%S\" unknown", old_name);
  3092. X    if
  3093. X    (
  3094. X        p_src_data->usage == file_usage_test
  3095. X    ||
  3096. X        p_src_data->usage == file_usage_manual_test
  3097. X    )
  3098. X        project_fatal(pp, "may not move tests");
  3099. X
  3100. X    /*
  3101. X     * ensure that the new file
  3102. X     * 1. is not already part of the change
  3103. X     * 2. is not in the baseline
  3104. X     */
  3105. X    if (change_src_find(cp, new_name))
  3106. X        change_fatal(cp, "file \"%S\" already in change", new_name);
  3107. X    p_src_data = project_src_find(pp, new_name);
  3108. X    if
  3109. X    (
  3110. X        p_src_data
  3111. X    &&
  3112. X        !p_src_data->about_to_be_created_by
  3113. X    &&
  3114. X        !p_src_data->deleted_by
  3115. X    )
  3116. X    {
  3117. X        project_fatal
  3118. X        (
  3119. X            pp,
  3120. X            "file \"%S\" is already in the baseline",
  3121. X            new_name
  3122. X        );
  3123. X    }
  3124. X
  3125. X    /*
  3126. X     * Copy the file into the development directory.
  3127. X     * Create any necessary directories along the way.
  3128. X     */
  3129. X    from = str_format("%S/%S", bl, old_name);
  3130. X    to = str_format("%S/%S", dd, new_name);
  3131. X    user_become(up);
  3132. X    os_mkdir_between(dd, new_name, 02755);
  3133. X    copy_whole_file(from, to, 0);
  3134. X    user_become_undo();
  3135. X    str_free(from);
  3136. X    str_free(to);
  3137. X
  3138. X    /*
  3139. X     * Add the files to the change
  3140. X     */
  3141. X    p_src_data = project_src_find(pp, old_name);
  3142. X    assert(p_src_data);
  3143. X    c_src_data = change_src_new(cp);
  3144. X    c_src_data->file_name = str_copy(old_name);
  3145. X    c_src_data->action = file_action_remove;
  3146. X    c_src_data->usage = p_src_data->usage;
  3147. X    c_src_data->move = str_copy(new_name);
  3148. X    c_src_data->edit_number = str_copy(p_src_data->edit_number);
  3149. X
  3150. X    c_src_data = change_src_new(cp);
  3151. X    c_src_data->file_name = str_copy(new_name);
  3152. X    c_src_data->action = file_action_create;
  3153. X    c_src_data->usage = p_src_data->usage;
  3154. X    c_src_data->move = str_copy(old_name);
  3155. X
  3156. X    /*
  3157. X     * the number of files changed,
  3158. X     * so stomp on the validation fields.
  3159. X     */
  3160. X    cstate_data->build_time = 0;
  3161. X    cstate_data->test_time = 0;
  3162. X    cstate_data->test_baseline_time = 0;
  3163. X    cstate_data->regression_test_time = 0;
  3164. X
  3165. X    /*
  3166. X     * release the locks
  3167. X     */
  3168. X    change_cstate_write(cp);
  3169. X    commit();
  3170. X    lock_release();
  3171. X
  3172. X    /*
  3173. X     * verbose success message
  3174. X     */
  3175. X    change_verbose(cp, "file \"%S\" moving to \"%S\"", old_name, new_name);
  3176. X
  3177. X    /*
  3178. X     * run the change file command
  3179. X     */
  3180. X    if (!nolog)
  3181. X        log_open(change_logfile_get(cp), up);
  3182. X    wl_zero(&wl);
  3183. X    wl_append(&wl, old_name);
  3184. X    wl_append(&wl, new_name);
  3185. X    change_run_change_file_command(cp, &wl, up);
  3186. X    wl_free(&wl);
  3187. X    str_free(old_name);
  3188. X    str_free(new_name);
  3189. X    project_free(pp);
  3190. X    change_free(cp);
  3191. X    user_free(up);
  3192. X    trace((/*{*/"}\n"));
  3193. X}
  3194. X
  3195. X
  3196. Xvoid
  3197. Xmove_file()
  3198. X{
  3199. X    trace(("move_file()\n{\n"/*}*/));
  3200. X    switch (arglex())
  3201. X    {
  3202. X    default:
  3203. X        move_file_main();
  3204. X        break;
  3205. X
  3206. X    case arglex_token_help:
  3207. X        move_file_help();
  3208. X        break;
  3209. X
  3210. X    case arglex_token_list:
  3211. X        move_file_list();
  3212. X        break;
  3213. X    }
  3214. X    trace((/*{*/"}\n"));
  3215. X}
  3216. END_OF_FILE
  3217. if test 14640 -ne `wc -c <'aegis/aemv.c'`; then
  3218.     echo shar: \"'aegis/aemv.c'\" unpacked with wrong size!
  3219. fi
  3220. # end of 'aegis/aemv.c'
  3221. fi
  3222. if test -f 'aegis/aepa.c' -a "${1}" != "-c" ; then 
  3223.   echo shar: Will not clobber existing file \"'aegis/aepa.c'\"
  3224. else
  3225. echo shar: Extracting \"'aegis/aepa.c'\" \(15749 characters\)
  3226. sed "s/^X//" >'aegis/aepa.c' <<'END_OF_FILE'
  3227. X/*
  3228. X *    aegis - project change supervisor
  3229. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  3230. X *    All rights reserved.
  3231. X *
  3232. X *    This program is free software; you can redistribute it and/or modify
  3233. X *    it under the terms of the GNU General Public License as published by
  3234. X *    the Free Software Foundation; either version 2 of the License, or
  3235. X *    (at your option) any later version.
  3236. X *
  3237. X *    This program is distributed in the hope that it will be useful,
  3238. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  3239. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3240. X *    GNU General Public License for more details.
  3241. X *
  3242. X *    You should have received a copy of the GNU General Public License
  3243. X *    along with this program; if not, write to the Free Software
  3244. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3245. X *
  3246. X * MANIFEST: functions to list and modify project attributes
  3247. X */
  3248. X
  3249. X#include <stdio.h>
  3250. X#include <stdlib.h>
  3251. X
  3252. X#include <aepa.h>
  3253. X#include <arglex2.h>
  3254. X#include <commit.h>
  3255. X#include <conf.h>
  3256. X#include <error.h>
  3257. X#include <help.h>
  3258. X#include <lock.h>
  3259. X#include <option.h>
  3260. X#include <os.h>
  3261. X#include <pattr.h>
  3262. X#include <project.h>
  3263. X#include <trace.h>
  3264. X#include <user.h>
  3265. X
  3266. X
  3267. Xstatic void project_attributes_usage _((void));
  3268. X
  3269. Xstatic void
  3270. Xproject_attributes_usage()
  3271. X{
  3272. X    char        *progname;
  3273. X
  3274. X    progname = option_progname_get();
  3275. X    fprintf(stderr, "usage: %s -Project_Attributes <attr-file> [ <option>... ]\n", progname);
  3276. X    fprintf(stderr, "       %s -Project_Attributes -Edit [ <option>... ]\n", progname);
  3277. X    fprintf(stderr, "       %s -Project_Attributes -List [ <option>... ]\n", progname);
  3278. X    fprintf(stderr, "       %s -Project_Attributes -Help\n", progname);
  3279. X    quit(1);
  3280. X}
  3281. X
  3282. X
  3283. Xstatic void project_attributes_help _((void));
  3284. X
  3285. Xstatic void
  3286. Xproject_attributes_help()
  3287. X{
  3288. X    static char *text[] =
  3289. X    {
  3290. X"NAME",
  3291. X"    %s -Project_Attributes - modify the attributes of a",
  3292. X"    project",
  3293. X"",
  3294. X"SYNOPSIS",
  3295. X"    %s -Project_Attributes <attr-file> [ <option>... ]",
  3296. X"    %s -Project_Attributes -Edit [ <option>... ]",
  3297. X"    %s -Project_Attributes -List [ <option>... ]",
  3298. X"    %s -Project_Attributes -Help",
  3299. X"",
  3300. X"DESCRIPTION",
  3301. X"    The %s -Project_Attributes command is used to set,",
  3302. X"    edit or list the attributes of a project.",
  3303. X"",
  3304. X"    The output of the -List variant is suitable for use as",
  3305. X"    input at a later time.",
  3306. X"",
  3307. X"    See aepattr(5) for a description of the file format.",
  3308. X"",
  3309. X"OPTIONS",
  3310. X"    The following options are understood:",
  3311. X"",
  3312. X"    -Edit",
  3313. X"        Edit the attributes with a text editor, this is",
  3314. X"        usually more convenient than supplying a text",
  3315. X"        file.  The EDITOR environment variable will be",
  3316. X"        consulted for the name of the editor to use;",
  3317. X"        defaults to vi(1) if not set.  Warning: not well",
  3318. X"        behaved when faced with errors, the temporary",
  3319. X"        file is always deleted.",
  3320. X"",
  3321. X"    -Help",
  3322. X"        This option may be used to obtain more",
  3323. X"        information about how to use the %s program.",
  3324. X"",
  3325. X"    -List",
  3326. X"        This option may be used to obtain a list of",
  3327. X"        suitable subjects for this command.  The list may",
  3328. X"        be more general than expected.",
  3329. X"",
  3330. X"    -Project <name>",
  3331. X"        This option may be used to select the project of",
  3332. X"        interest.  When no -Project option is specified, the",
  3333. X"        AEGIS_PROJECT environment variable is consulted.  If",
  3334. X"        that does not exist, the user's $HOME/.aegisrc file",
  3335. X"        is examined for a default project field (see",
  3336. X"        aeuconf(5) for more information).  If that does not",
  3337. X"        exist, when the user is only working on changes",
  3338. X"        within a single project, the project name defaults",
  3339. X"        to that project.  Otherwise, it is an error.",
  3340. X"",
  3341. X"    -TERse",
  3342. X"        This option may be used to cause listings to",
  3343. X"        produce the bare minimum of information.  It is",
  3344. X"        usually useful for shell scripts.",
  3345. X"",
  3346. X"    -Verbose",
  3347. X"        This option may be used to cause %s to produce",
  3348. X"        more output.  By default %s only produces",
  3349. X"        output on errors.  When used with the -List",
  3350. X"        option this option causes column headings to be",
  3351. X"        added.",
  3352. X"",
  3353. X"    All options may be abbreviated; the abbreviation is",
  3354. X"    documented as the upper case letters, all lower case",
  3355. X"    letters and underscores (_) are optional.  You must use",
  3356. X"    consecutive sequences of optional letters.",
  3357. X"",
  3358. X"    All options are case insensitive, you may type them in",
  3359. X"    upper case or lower case or a combination of both, case",
  3360. X"    is not important.",
  3361. X"",
  3362. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  3363. X"    are all interpreted to mean the -Project option.  The",
  3364. X"    argument \"-prj\" will not be understood, because",
  3365. X"    consecutive optional characters were not supplied.",
  3366. X"",
  3367. X"    Options and other command line arguments may be mixed",
  3368. X"    arbitrarily on the command line, after the function",
  3369. X"    selectors.",
  3370. X"",
  3371. X"    The GNU long option names are understood.  Since all",
  3372. X"    option names for aegis are long, this means ignoring the",
  3373. X"    extra leading '-'.  The \"--option=value\" convention is",
  3374. X"    also understood.",
  3375. X"",
  3376. X"RECOMMENDED ALIAS",
  3377. X"    The recommended alias for this command is",
  3378. X"    csh%%    alias aepa '%s -pa \\!* -v'",
  3379. X"    sh$    aepa(){%s -pa $* -v}",
  3380. X"",
  3381. X"ERRORS",
  3382. X"    It is an error if the current user is not an",
  3383. X"    administrator of the specified project.",
  3384. X"",
  3385. X"EXIT STATUS",
  3386. X"    The %s command will exit with a status of 1 on any",
  3387. X"    error.    The %s command will only exit with a status of",
  3388. X"    0 if there are no errors.",
  3389. X"",
  3390. X"COPYRIGHT",
  3391. X"    %C",
  3392. X"",
  3393. X"AUTHOR",
  3394. X"    %A",
  3395. X    };
  3396. X
  3397. X    help(text, SIZEOF(text), project_attributes_usage);
  3398. X}
  3399. X
  3400. X
  3401. Xstatic void pattr_copy _((pattr, pstate));
  3402. X
  3403. Xstatic void
  3404. Xpattr_copy(a, s)
  3405. X    pattr    a;
  3406. X    pstate    s;
  3407. X{
  3408. X    if (!a->description && s->description)
  3409. X        a->description = str_copy(s->description);
  3410. X    if (!a->owner_name && s->owner_name)
  3411. X        a->owner_name = str_copy(s->owner_name);
  3412. X    if (!a->group_name && s->group_name)
  3413. X        a->group_name = str_copy(s->group_name);
  3414. X    if
  3415. X    (
  3416. X        !a->default_development_directory
  3417. X    &&
  3418. X        s->default_development_directory
  3419. X    )
  3420. X        a->default_development_directory =
  3421. X            str_copy(s->default_development_directory);
  3422. X
  3423. X    if (!(a->mask & pattr_developer_may_review_mask))
  3424. X        a->developer_may_review = s->developer_may_review;
  3425. X    if (!(a->mask & pattr_developer_may_integrate_mask))
  3426. X        a->developer_may_integrate = s->developer_may_integrate;
  3427. X    if (!(a->mask & pattr_reviewer_may_integrate_mask))
  3428. X        a->reviewer_may_integrate = s->reviewer_may_integrate;
  3429. X    if (!(a->mask & pattr_developers_may_create_changes_mask))
  3430. X        a->developers_may_create_changes =
  3431. X            s->developers_may_create_changes;
  3432. X    if (!(a->mask & pattr_umask_mask))
  3433. X        a->umask = s->umask;
  3434. X    if (!(a->mask & pattr_default_test_exemption_mask))
  3435. X        a->default_test_exemption = s->default_test_exemption;
  3436. X
  3437. X    if (!a->develop_end_notify_command && s->develop_end_notify_command)
  3438. X        a->develop_end_notify_command =
  3439. X            str_copy(s->develop_end_notify_command);
  3440. X    if
  3441. X    (
  3442. X        !a->develop_end_undo_notify_command
  3443. X    &&
  3444. X        s->develop_end_undo_notify_command
  3445. X    )
  3446. X        a->develop_end_undo_notify_command =
  3447. X            str_copy(s->develop_end_undo_notify_command);
  3448. X    if
  3449. X    (
  3450. X        !a->review_pass_notify_command
  3451. X    &&
  3452. X        s->review_pass_notify_command
  3453. X    )
  3454. X        a->review_pass_notify_command =
  3455. X            str_copy(s->review_pass_notify_command);
  3456. X    if
  3457. X    (
  3458. X        !a->review_pass_undo_notify_command
  3459. X    &&
  3460. X        s->review_pass_undo_notify_command
  3461. X    )
  3462. X        a->review_pass_undo_notify_command =
  3463. X            str_copy(s->review_pass_undo_notify_command);
  3464. X    if
  3465. X    (
  3466. X        !a->review_fail_notify_command
  3467. X    &&
  3468. X        s->review_fail_notify_command
  3469. X    )
  3470. X        a->review_fail_notify_command =
  3471. X            str_copy(s->review_fail_notify_command);
  3472. X    if
  3473. X    (
  3474. X        !a->integrate_pass_notify_command
  3475. X    &&
  3476. X        s->integrate_pass_notify_command
  3477. X    )
  3478. X        a->integrate_pass_notify_command =
  3479. X            str_copy(s->integrate_pass_notify_command);
  3480. X    if
  3481. X    (
  3482. X        !a->integrate_fail_notify_command
  3483. X    &&
  3484. X        s->integrate_fail_notify_command
  3485. X    )
  3486. X        a->integrate_fail_notify_command =
  3487. X            str_copy(s->integrate_fail_notify_command);
  3488. X}
  3489. X
  3490. X
  3491. Xstatic void project_attributes_list _((void));
  3492. X
  3493. Xstatic void
  3494. Xproject_attributes_list()
  3495. X{
  3496. X    pattr        pattr_data;
  3497. X    pstate        pstate_data;
  3498. X    string_ty    *project_name;
  3499. X    project_ty    *pp;
  3500. X
  3501. X    trace(("project_attributes_list()\n{\n"/*}*/));
  3502. X    project_name = 0;
  3503. X    arglex();
  3504. X    while (arglex_token != arglex_token_eoln)
  3505. X    {
  3506. X        switch (arglex_token)
  3507. X        {
  3508. X        default:
  3509. X            generic_argument(project_attributes_usage);
  3510. X            continue;
  3511. X
  3512. X        case arglex_token_project:
  3513. X            if (arglex() != arglex_token_string)
  3514. X                project_attributes_usage();
  3515. X            /* fall through... */
  3516. X
  3517. X        case arglex_token_string:
  3518. X            if (project_name)
  3519. X                fatal("duplicate -Project option");
  3520. X            project_name = str_from_c(arglex_value.alv_string);
  3521. X            break;
  3522. X        }
  3523. X        arglex();
  3524. X    }
  3525. X
  3526. X    /*
  3527. X     * locate project data
  3528. X     */
  3529. X    if (!project_name)
  3530. X        project_name = user_default_project();
  3531. X    pp = project_alloc(project_name);
  3532. X    str_free(project_name);
  3533. X    project_bind_existing(pp);
  3534. X
  3535. X    pstate_data = project_pstate_get(pp);
  3536. X    pattr_data = (pattr)pattr_type.alloc();
  3537. X    pattr_copy(pattr_data, pstate_data);
  3538. X    pattr_write_file((char *)0, pattr_data);
  3539. X    pattr_type.free(pattr_data);
  3540. X    project_free(pp);
  3541. X    trace((/*{*/"}\n"));
  3542. X}
  3543. X
  3544. X
  3545. Xstatic void pattr_edit _((pattr *));
  3546. X
  3547. Xstatic void
  3548. Xpattr_edit(dp)
  3549. X    pattr        *dp;
  3550. X{
  3551. X    pattr        d;
  3552. X    string_ty    *filename;
  3553. X    
  3554. X    /*
  3555. X     * write attributes to temporary file
  3556. X     */
  3557. X    d = *dp;
  3558. X    assert(d);
  3559. X    filename = os_edit_filename();
  3560. X    os_become_orig();
  3561. X    pattr_write_file(filename->str_text, d);
  3562. X    pattr_type.free(d);
  3563. X
  3564. X    /*
  3565. X     * edit the file
  3566. X     */
  3567. X    os_edit(filename);
  3568. X
  3569. X    /*
  3570. X     * read it in again
  3571. X     */
  3572. X    d = pattr_read_file(filename->str_text);
  3573. X    os_unlink(filename);
  3574. X    os_become_undo();
  3575. X    str_free(filename);
  3576. X    *dp = d;
  3577. X}
  3578. X
  3579. X
  3580. Xstatic void project_attributes_main _((void));
  3581. X
  3582. Xstatic void
  3583. Xproject_attributes_main()
  3584. X{
  3585. X    pattr        pattr_data = 0;
  3586. X    pstate        pstate_data;
  3587. X    string_ty    *project_name;
  3588. X    project_ty    *pp;
  3589. X    string_ty    *s;
  3590. X    int        edit;
  3591. X    user_ty        *up;
  3592. X
  3593. X    trace(("project_attributes_main()\n{\n"/*}*/));
  3594. X    project_name = 0;
  3595. X    edit = 0;
  3596. X    while (arglex_token != arglex_token_eoln)
  3597. X    {
  3598. X        switch (arglex_token)
  3599. X        {
  3600. X        default:
  3601. X            generic_argument(project_attributes_usage);
  3602. X            continue;
  3603. X
  3604. X        case arglex_token_string:
  3605. X            if (pattr_data)
  3606. X                fatal("too many files named");
  3607. X            os_become_orig();
  3608. X            pattr_data = pattr_read_file(arglex_value.alv_string);
  3609. X            os_become_undo();
  3610. X            assert(pattr_data);
  3611. X            break;
  3612. X
  3613. X        case arglex_token_project:
  3614. X            if (arglex() != arglex_token_string)
  3615. X                project_attributes_usage();
  3616. X            if (project_name)
  3617. X                fatal("duplicate -Project option");
  3618. X            project_name = str_from_c(arglex_value.alv_string);
  3619. X            break;
  3620. X
  3621. X        case arglex_token_edit:
  3622. X            if (edit)
  3623. X                fatal("duplicate %s option", arglex_value.alv_string);
  3624. X            edit++;
  3625. X            break;
  3626. X        }
  3627. X        arglex();
  3628. X    }
  3629. X    if (edit && !pattr_data)
  3630. X        pattr_data = (pattr)pattr_type.alloc();
  3631. X    if (!pattr_data)
  3632. X        fatal("no project attributes file named");
  3633. X
  3634. X    /*
  3635. X     * locate project data
  3636. X     */
  3637. X    if (!project_name)
  3638. X        project_name = user_default_project();
  3639. X    pp = project_alloc(project_name);
  3640. X    str_free(project_name);
  3641. X    project_bind_existing(pp);
  3642. X
  3643. X    /*
  3644. X     * locate user data
  3645. X     */
  3646. X    up = user_executing(pp);
  3647. X
  3648. X    /*
  3649. X     * edit the attributes
  3650. X     */
  3651. X    if (edit)
  3652. X    {
  3653. X        /*
  3654. X         * copy things from project
  3655. X         */
  3656. X        pstate_data = project_pstate_get(pp);
  3657. X        pattr_copy(pattr_data, pstate_data);
  3658. X
  3659. X        /*
  3660. X         * edit them
  3661. X         */
  3662. X        pattr_edit(&pattr_data);
  3663. X    }
  3664. X
  3665. X    /*
  3666. X     * take project lock
  3667. X     */
  3668. X    project_pstate_lock_prepare(pp);
  3669. X    lock_take();
  3670. X    pstate_data = project_pstate_get(pp);
  3671. X
  3672. X    /*
  3673. X     * it is an error if the user is not an administrator
  3674. X     */
  3675. X    if (!project_administrator_query(pp, user_name(up)))
  3676. X    {
  3677. X        project_fatal
  3678. X        (
  3679. X            pp,
  3680. X             "attributes may only be changed by a project administrator"
  3681. X        );
  3682. X    }
  3683. X
  3684. X    if (pattr_data->description)
  3685. X    {
  3686. X        if (pstate_data->description)
  3687. X            str_free(pstate_data->description);
  3688. X        pstate_data->description = str_copy(pattr_data->description);
  3689. X    }
  3690. X
  3691. X    if (pattr_data->owner_name)
  3692. X    {
  3693. X        if (!user_uid_check(pattr_data->owner_name))
  3694. X        {
  3695. X            fatal
  3696. X            (
  3697. X                "user \"%s\" is too privileged",
  3698. X                pattr_data->owner_name->str_text
  3699. X            );
  3700. X        }
  3701. X        if (pstate_data->owner_name)
  3702. X            str_free(pstate_data->owner_name);
  3703. X        pstate_data->owner_name = str_copy(pattr_data->owner_name);
  3704. X    }
  3705. X
  3706. X    if (pattr_data->group_name)
  3707. X    {
  3708. X        if (!user_gid_check(pattr_data->group_name))
  3709. X        {
  3710. X            fatal
  3711. X            (
  3712. X                "group \"%s\" is too privileged",
  3713. X                pattr_data->group_name->str_text
  3714. X            );
  3715. X        }
  3716. X        if (pstate_data->group_name)
  3717. X            str_free(pstate_data->group_name);
  3718. X        pstate_data->group_name = str_copy(pattr_data->group_name);
  3719. X    }
  3720. X
  3721. X    if (pattr_data->mask & pattr_developer_may_review_mask)
  3722. X        pstate_data->developer_may_review =
  3723. X            pattr_data->developer_may_review;
  3724. X    if (pattr_data->mask & pattr_developer_may_integrate_mask)
  3725. X        pstate_data->developer_may_integrate =
  3726. X            pattr_data->developer_may_integrate;
  3727. X    if (pattr_data->mask & pattr_reviewer_may_integrate_mask)
  3728. X        pstate_data->reviewer_may_integrate =
  3729. X            pattr_data->reviewer_may_integrate;
  3730. X    if (pattr_data->mask & pattr_developers_may_create_changes_mask)
  3731. X        pstate_data->developers_may_create_changes =
  3732. X            pattr_data->developers_may_create_changes;
  3733. X
  3734. X    /*
  3735. X     * only some combos work,
  3736. X     * umask is basically for the "other" permissions
  3737. X     */
  3738. X    if (pattr_data->mask & pattr_umask_mask)
  3739. X        pstate_data->umask = (pattr_data->umask & 5) | 022;
  3740. X    
  3741. X    if (pattr_data->mask & pattr_default_test_exemption_mask)
  3742. X        pstate_data->default_test_exemption =
  3743. X            pattr_data->default_test_exemption;
  3744. X
  3745. X    if (pattr_data->develop_end_notify_command)
  3746. X    {
  3747. X        if (pstate_data->develop_end_notify_command)
  3748. X            str_free(pstate_data->develop_end_notify_command);
  3749. X        pstate_data->develop_end_notify_command =
  3750. X            str_copy(pattr_data->develop_end_notify_command);
  3751. X    }
  3752. X
  3753. X    if (pattr_data->develop_end_undo_notify_command)
  3754. X    {
  3755. X        if (pstate_data->develop_end_undo_notify_command)
  3756. X            str_free(pstate_data->develop_end_undo_notify_command);
  3757. X        pstate_data->develop_end_undo_notify_command =
  3758. X            str_copy(pattr_data->develop_end_undo_notify_command);
  3759. X    }
  3760. X
  3761. X    if (pattr_data->review_pass_notify_command)
  3762. X    {
  3763. X        if (pstate_data->review_pass_notify_command)
  3764. X            str_free(pstate_data->review_pass_notify_command);
  3765. X        pstate_data->review_pass_notify_command =
  3766. X            str_copy(pattr_data->review_pass_notify_command);
  3767. X    }
  3768. X
  3769. X    if (pattr_data->review_pass_undo_notify_command)
  3770. X    {
  3771. X        if (pstate_data->review_pass_undo_notify_command)
  3772. X            str_free(pstate_data->review_pass_undo_notify_command);
  3773. X        pstate_data->review_pass_undo_notify_command =
  3774. X            str_copy(pattr_data->review_pass_undo_notify_command);
  3775. X    }
  3776. X
  3777. X    if (pattr_data->review_fail_notify_command)
  3778. X    {
  3779. X        if (pstate_data->review_fail_notify_command)
  3780. X            str_free(pstate_data->review_fail_notify_command);
  3781. X        pstate_data->review_fail_notify_command =
  3782. X            str_copy(pattr_data->review_fail_notify_command);
  3783. X    }
  3784. X
  3785. X    if (pattr_data->integrate_pass_notify_command)
  3786. X    {
  3787. X        if (pstate_data->integrate_pass_notify_command)
  3788. X            str_free(pstate_data->integrate_pass_notify_command);
  3789. X        pstate_data->integrate_pass_notify_command =
  3790. X            str_copy(pattr_data->integrate_pass_notify_command);
  3791. X    }
  3792. X
  3793. X    if (pattr_data->integrate_fail_notify_command)
  3794. X    {
  3795. X        if (pstate_data->integrate_fail_notify_command)
  3796. X            str_free(pstate_data->integrate_fail_notify_command);
  3797. X        pstate_data->integrate_fail_notify_command =
  3798. X            str_copy(pattr_data->integrate_fail_notify_command);
  3799. X    }
  3800. X
  3801. X    if (pattr_data->default_development_directory)
  3802. X    {
  3803. X        if (pstate_data->default_development_directory)
  3804. X            str_free(pstate_data->default_development_directory);
  3805. X        s = pattr_data->default_development_directory;
  3806. X        if (!s->str_length)
  3807. X            pstate_data->default_development_directory = 0;
  3808. X        else
  3809. X        {
  3810. X            if (s->str_text[0] != '/')
  3811. X            {
  3812. X                fatal
  3813. X                (
  3814. X    "default development directory must be specified as an absolute path"
  3815. X                );
  3816. X            }
  3817. X            pstate_data->default_development_directory =
  3818. X                str_copy(s);
  3819. X        }
  3820. X    }
  3821. X
  3822. X    pattr_type.free(pattr_data);
  3823. X    project_pstate_write(pp);
  3824. X    commit();
  3825. X    lock_release();
  3826. X    project_verbose(pp, "attributes changed");
  3827. X    project_free(pp);
  3828. X    user_free(up);
  3829. X    trace((/*{*/"}\n"));
  3830. X}
  3831. X
  3832. X
  3833. Xvoid
  3834. Xproject_attributes()
  3835. X{
  3836. X    trace(("project_attributes()\n{\n"/*}*/));
  3837. X    switch (arglex())
  3838. X    {
  3839. X    default:
  3840. X        project_attributes_main();
  3841. X        break;
  3842. X
  3843. X    case arglex_token_help:
  3844. X        project_attributes_help();
  3845. X        break;
  3846. X
  3847. X    case arglex_token_list:
  3848. X        project_attributes_list();
  3849. X        break;
  3850. X    }
  3851. X    trace((/*{*/"}\n"));
  3852. X}
  3853. END_OF_FILE
  3854. if test 15749 -ne `wc -c <'aegis/aepa.c'`; then
  3855.     echo shar: \"'aegis/aepa.c'\" unpacked with wrong size!
  3856. fi
  3857. # end of 'aegis/aepa.c'
  3858. fi
  3859. if test -f 'aegis/gonzo.c' -a "${1}" != "-c" ; then 
  3860.   echo shar: Will not clobber existing file \"'aegis/gonzo.c'\"
  3861. else
  3862. echo shar: Extracting \"'aegis/gonzo.c'\" \(16800 characters\)
  3863. sed "s/^X//" >'aegis/gonzo.c' <<'END_OF_FILE'
  3864. X/*
  3865. X *    aegis - project change supervisor
  3866. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  3867. X *    All rights reserved.
  3868. X *
  3869. X *    This program is free software; you can redistribute it and/or modify
  3870. X *    it under the terms of the GNU General Public License as published by
  3871. X *    the Free Software Foundation; either version 2 of the License, or
  3872. X *    (at your option) any later version.
  3873. X *
  3874. X *    This program is distributed in the hope that it will be useful,
  3875. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  3876. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3877. X *    GNU General Public License for more details.
  3878. X *
  3879. X *    You should have received a copy of the GNU General Public License
  3880. X *    along with this program; if not, write to the Free Software
  3881. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3882. X *
  3883. X * MANIFEST: functions for manipulating global state data
  3884. X */
  3885. X
  3886. X#include <stdio.h>
  3887. X#include <stdlib.h>
  3888. X#include <string.h>
  3889. X#include <unistd.h>
  3890. X
  3891. X#include <commit.h>
  3892. X#include <conf.h>
  3893. X#include <error.h>
  3894. X#include <gonzo.h>
  3895. X#include <gstate.h>
  3896. X#include <lock.h>
  3897. X#include <mem.h>
  3898. X#include <option.h>
  3899. X#include <os.h>
  3900. X#include <project.h>
  3901. X#include <trace.h>
  3902. X#include <undo.h>
  3903. X#include <user.h>
  3904. X#include <ustate.h>
  3905. X#include <word.h>
  3906. X
  3907. Xtypedef struct gonzo_ty gonzo_ty;
  3908. Xstruct gonzo_ty
  3909. X{
  3910. X    string_ty    *dir;
  3911. X    string_ty    *gstate_filename;
  3912. X    gstate        gstate_data;
  3913. X    int        is_a_new_file;
  3914. X    int        modified;
  3915. X    long        lock_magic;
  3916. X    int        temporary;
  3917. X};
  3918. X
  3919. Xstatic    size_t        ngonzos;
  3920. Xstatic    gonzo_ty    **gonzo;
  3921. Xstatic    int        done_tail;
  3922. X
  3923. X
  3924. Xstatic user_ty *gonzo_user _((void));
  3925. X
  3926. Xstatic user_ty *
  3927. Xgonzo_user()
  3928. X{
  3929. X    static user_ty    *u;
  3930. X
  3931. X    if (!u)
  3932. X    {
  3933. X        string_ty    *s;
  3934. X
  3935. X        s = str_from_c(AEGIS_USER);
  3936. X        u = user_symbolic((project_ty *)0, s);
  3937. X        u->umask = 022;
  3938. X        str_free(s);
  3939. X    }
  3940. X    return u;
  3941. X}
  3942. X
  3943. X
  3944. Xstatic int is_temporary _((string_ty *));
  3945. X
  3946. Xstatic int
  3947. Xis_temporary(s)
  3948. X    string_ty    *s;
  3949. X{
  3950. X    return
  3951. X    (
  3952. X        !strncmp(s->str_text, "/tmp/", 5)
  3953. X    ||
  3954. X        !strncmp(s->str_text, "/usr/tmp/", 9)
  3955. X    ||
  3956. X        !strncmp(s->str_text, "/var/tmp/", 9)
  3957. X    );
  3958. X}
  3959. X
  3960. X
  3961. Xvoid
  3962. Xgonzo_library_append(s)
  3963. X    char        *s;
  3964. X{
  3965. X    gonzo_ty    *gp;
  3966. X    string_ty    *tmp;
  3967. X    string_ty    *dir;
  3968. X
  3969. X    /*
  3970. X     * resolve the pathname
  3971. X     */
  3972. X    trace(("gonzo_library_append(s = \"%s\")\n{\n"/*}*/, s));
  3973. X    assert(s);
  3974. X    assert(!done_tail);
  3975. X    tmp = str_from_c(s);
  3976. X    os_become_orig();
  3977. X    dir = os_pathname(tmp, 1);
  3978. X    os_become_undo();
  3979. X    str_free(tmp);
  3980. X
  3981. X    /*
  3982. X     * append the new entry to the end of the list
  3983. X     */
  3984. X    gp = (gonzo_ty *)mem_alloc_clear(sizeof(gonzo_ty));
  3985. X    gp->dir = dir;
  3986. X    gp->temporary = is_temporary(dir);
  3987. X    gp->gstate_filename = str_format("%S/state", gp->dir);
  3988. X    *(gonzo_ty **)
  3989. X    enlarge
  3990. X    (
  3991. X        &ngonzos,
  3992. X        (char **)&gonzo, sizeof(gonzo_ty *)
  3993. X    ) =
  3994. X        gp;
  3995. X    trace((/*{*/"}\n"));
  3996. X}
  3997. X
  3998. X
  3999. Xstatic void lock_sync _((gonzo_ty *));
  4000. X
  4001. Xstatic void
  4002. Xlock_sync(gp)
  4003. X    gonzo_ty    *gp;
  4004. X{
  4005. X    long        n;
  4006. X
  4007. X    trace(("lock_sync(gp = %08lX)\n{\n"/*}*/, gp));
  4008. X    n = lock_magic();
  4009. X    if (gp->lock_magic == n)
  4010. X        goto ret;
  4011. X    gp->lock_magic = n;
  4012. X
  4013. X    if (gp->gstate_data && !gp->is_a_new_file)
  4014. X    {
  4015. X        gstate_type.free(gp->gstate_data);
  4016. X        gp->gstate_data = 0;
  4017. X    }
  4018. X    ret:
  4019. X    trace((/*{*/"}\n"));
  4020. X}
  4021. X
  4022. X
  4023. X
  4024. Xstatic gstate gonzo_gstate_get _((gonzo_ty *));
  4025. X
  4026. Xstatic gstate
  4027. Xgonzo_gstate_get(gp)
  4028. X    gonzo_ty    *gp;
  4029. X{
  4030. X    trace(("gonzo_gstate_get(gp = %08lX)\n{\n"/*}*/, gp));
  4031. X    lock_sync(gp);
  4032. X    if (!gp->gstate_data)
  4033. X    {
  4034. X        gonzo_become();
  4035. X        gp->is_a_new_file = !os_exists(gp->gstate_filename);
  4036. X        if (!gp->is_a_new_file)
  4037. X        {
  4038. X            os_chown_check
  4039. X            (
  4040. X                gp->gstate_filename,
  4041. X                0644,
  4042. X                user_id(gonzo_user()),
  4043. X                user_gid(gonzo_user())
  4044. X            );
  4045. X            gp->gstate_data =
  4046. X                gstate_read_file(gp->gstate_filename->str_text);
  4047. X        }
  4048. X        else
  4049. X            gp->gstate_data = (gstate)gstate_type.alloc();
  4050. X        if (!gp->gstate_data->where)
  4051. X            gp->gstate_data->where =
  4052. X                (gstate_where_list)
  4053. X                gstate_where_list_type.alloc();
  4054. X        gonzo_become_undo();
  4055. X    }
  4056. X    trace(("return %08lX;\n", gp->gstate_data));
  4057. X    trace((/*{*/"}\n"));
  4058. X    return gp->gstate_data;
  4059. X}
  4060. X
  4061. X
  4062. X/*
  4063. X * NAME
  4064. X *    construct_library_directory
  4065. X *
  4066. X * SYNOPSIS
  4067. X *    void construct_library_directory(gonzo_ty *gp);
  4068. X *
  4069. X * DESCRIPTION
  4070. X *    The construct_library_directory function is used to
  4071. X *    construct missing elements of the aegis library search path.
  4072. X *    These elements must be constructed with great care so that
  4073. X *    they may work on NFS mounted disks of "data-less" clients.
  4074. X *
  4075. X *    The path up to, but not including, the library directory must
  4076. X *    be owned by the executing user.  The actions will fail if the
  4077. X *    executing user does not have sufficient permissions, as
  4078. X *    one would expect.
  4079. X *
  4080. X *    The library directory itself must be owned by AEGIS_USER.
  4081. X *    This is to defend against tampering and ignorance.
  4082. X *    Having this change of ownership requires some fast footwork
  4083. X *    with chmod's to allow AEGIS_USER temporary access.
  4084. X *
  4085. X * ARGUMENTS
  4086. X *    gp    - library directory to act upon
  4087. X *
  4088. X * CAVEAT
  4089. X *    The chown() system call will not work on data-less clients,
  4090. X *    because the remote hosts which owns the NFS mounted disks
  4091. X *    will rarely trust the local "root" user, and map all
  4092. X *    foreign "root" users to the "unknown" user instead.
  4093. X */
  4094. X
  4095. Xstatic void construct_library_directory _((gonzo_ty *));
  4096. X
  4097. Xstatic void
  4098. Xconstruct_library_directory(gp)
  4099. X    gonzo_ty    *gp;
  4100. X{
  4101. X    int        exists;
  4102. X    string_ty    *above;
  4103. X    string_ty    *above2;
  4104. X    string_ty    *root;
  4105. X    int        mode;
  4106. X    
  4107. X    /*
  4108. X     * If the library directory already exists,
  4109. X     * then we need do nothing.
  4110. X     */
  4111. X    os_become_orig();
  4112. X    exists = os_exists(gp->dir);
  4113. X    if (exists)
  4114. X    {
  4115. X        os_become_undo();
  4116. X        return;
  4117. X    }
  4118. X
  4119. X    /*
  4120. X     * Construct all directories up to,
  4121. X     * but not including, the library directory,
  4122. X     * if they do not already exist.
  4123. X     * Construct these directories as the original user,
  4124. X     * possibly discovering relevant permission problems.
  4125. X     */
  4126. X    above = os_dirname(gp->dir);
  4127. X    above2 = str_n_from_c(above->str_text + 1, above->str_length - 1);
  4128. X    root = str_from_c("/");
  4129. X    os_mkdir_between(root, above2, 0755); /* NOT setgid */
  4130. X    str_free(root);
  4131. X    str_free(above2);
  4132. X
  4133. X    /*
  4134. X     * Get the mode of the directory containing the library directory,
  4135. X     * so that we may restore it later.  Change the mode to world
  4136. X     * writable, so that the library directory itself may be created
  4137. X     * belonging to gonzo.
  4138. X     */
  4139. X    mode = os_chmod_query(above);
  4140. X    mode |= 0111; /* minimum: all may search */
  4141. X    undo_chmod_errok(above, mode);
  4142. X    os_chmod(above, mode | 0777);
  4143. X    os_become_undo();
  4144. X
  4145. X    /*
  4146. X     * Create the library directory itself belonging to gonzo,
  4147. X     * and make sure it is world accessable.
  4148. X     *    (must be world writable in testing situations)
  4149. X     */
  4150. X    gonzo_become();
  4151. X    os_mkdir(gp->dir, 0755);
  4152. X    if (gp->temporary)
  4153. X        os_chmod(gp->dir, 0777);
  4154. X    gonzo_become_undo();
  4155. X
  4156. X    /*
  4157. X     * Restore permissions for the containing directory.
  4158. X     */
  4159. X    os_become_orig();
  4160. X    os_chmod(above, mode);
  4161. X    os_become_undo();
  4162. X    str_free(above);
  4163. X}
  4164. X
  4165. X
  4166. Xstatic void gonzo_gstate_write_sub _((gonzo_ty *));
  4167. X
  4168. Xstatic void
  4169. Xgonzo_gstate_write_sub(gp)
  4170. X    gonzo_ty    *gp;
  4171. X{
  4172. X    string_ty    *filename_new;
  4173. X    string_ty    *filename_old;
  4174. X    static int    count;
  4175. X
  4176. X    if (!gp->modified)
  4177. X        return;
  4178. X    trace(("gonzo_gstate_write_sub()\n{\n"/*}*/));
  4179. X    assert(gp->gstate_data);
  4180. X    assert(gp->gstate_filename);
  4181. X    filename_new = str_format("%S,%d", gp->gstate_filename, ++count);
  4182. X    filename_old = str_format("%S,%d", gp->gstate_filename, ++count);
  4183. X    if (gp->is_a_new_file)
  4184. X    {
  4185. X        construct_library_directory(gp);
  4186. X        gonzo_become();
  4187. X        undo_unlink_errok(filename_new);
  4188. X        gstate_write_file(filename_new->str_text, gp->gstate_data);
  4189. X        commit_rename(filename_new, gp->gstate_filename);
  4190. X        os_chmod(filename_new, 0644);
  4191. X        gonzo_become_undo();
  4192. X    }
  4193. X    else
  4194. X    {
  4195. X        gonzo_become();
  4196. X        undo_unlink_errok(filename_new);
  4197. X        gstate_write_file(filename_new->str_text, gp->gstate_data);
  4198. X        commit_rename(gp->gstate_filename, filename_old);
  4199. X        commit_rename(filename_new, gp->gstate_filename);
  4200. X        commit_unlink_errok(filename_old);
  4201. X        os_chmod(filename_new, 0644);
  4202. X        gonzo_become_undo();
  4203. X    }
  4204. X    str_free(filename_new);
  4205. X    str_free(filename_old);
  4206. X    gp->modified = 0;
  4207. X    trace((/*{*/"}\n"));
  4208. X}
  4209. X
  4210. X
  4211. Xstatic void do_tail _((void));
  4212. X
  4213. Xstatic void
  4214. Xdo_tail()
  4215. X{
  4216. X    string_ty    *s1;
  4217. X    string_ty    *s2;
  4218. X    char        *cp;
  4219. X    wlist        path;
  4220. X    size_t        j;
  4221. X
  4222. X    /*
  4223. X     * only do this once
  4224. X     */
  4225. X    if (done_tail)
  4226. X        return;
  4227. X
  4228. X    /*
  4229. X     * fetch the environment variable
  4230. X     */
  4231. X    trace(("do_tail()\n{\n"/*}*/));
  4232. X    s1 = str_from_c(option_progname_get());
  4233. X    s2 = str_upcase(s1);
  4234. X    str_free(s1);
  4235. X    cp = getenv(s2->str_text);
  4236. X    str_free(s2);
  4237. X    if (cp)
  4238. X    {
  4239. X        s1 = str_from_c(cp);
  4240. X        str2wl(&path, s1, ":");
  4241. X        str_free(s1);
  4242. X        for (j = 0; j < path.wl_nwords; ++j)
  4243. X        {
  4244. X            s1 = path.wl_word[j];
  4245. X            if (!os_testing_mode() || is_temporary(s1))
  4246. X                gonzo_library_append(s1->str_text);
  4247. X        }
  4248. X        wl_free(&path);
  4249. X    }
  4250. X
  4251. X    if (os_testing_mode())
  4252. X    {
  4253. X        if (!ngonzos)
  4254. X        {
  4255. X            fatal
  4256. X            (
  4257. X"There was no -LIBrary option specified.  This is mandatory in \"test\" mode."
  4258. X            );
  4259. X        }
  4260. X    }
  4261. X    else
  4262. X    {
  4263. X        /*
  4264. X         * always have the system one last
  4265. X         *    (this is where locks are taken)
  4266. X         */
  4267. X        gonzo_library_append(LIB);
  4268. X    }
  4269. X    done_tail = 1;
  4270. X    trace((/*{*/"}\n"));
  4271. X}
  4272. X
  4273. X
  4274. Xstatic gonzo_ty *gonzo_nth _((size_t));
  4275. X
  4276. Xstatic gonzo_ty *
  4277. Xgonzo_nth(j)
  4278. X    size_t        j;
  4279. X{
  4280. X    gonzo_ty    *result;
  4281. X
  4282. X    trace(("gonzo_nth(j = %ld)\n{\n"/*}*/, j));
  4283. X    do_tail();
  4284. X    if (j >= ngonzos)
  4285. X        result = 0;
  4286. X    else
  4287. X        result = gonzo[j];
  4288. X    trace(("return %08lX;\n", result));
  4289. X    trace((/*{*/"}\n"));
  4290. X    return result;
  4291. X}
  4292. X
  4293. X
  4294. Xvoid
  4295. Xgonzo_gstate_write()
  4296. X{
  4297. X    size_t        j;
  4298. X    gonzo_ty    *gp;
  4299. X
  4300. X    trace(("gonzo_gstate_write()\n{\n"/*}*/));
  4301. X    for (j = 0; ; ++j)
  4302. X    {
  4303. X        gp = gonzo_nth(j);
  4304. X        if (!gp)
  4305. X            break;
  4306. X        gonzo_gstate_write_sub(gp);
  4307. X    }
  4308. X    trace((/*{*/"}\n"));
  4309. X}
  4310. X
  4311. X
  4312. Xstatic string_ty *gonzo_project_home_path_sub _((gonzo_ty *, string_ty *));
  4313. X
  4314. Xstatic string_ty *
  4315. Xgonzo_project_home_path_sub(gp, name)
  4316. X    gonzo_ty    *gp;
  4317. X    string_ty    *name;
  4318. X{
  4319. X    gstate        gstate_data;
  4320. X    size_t        j;
  4321. X    string_ty    *result;
  4322. X
  4323. X    /*
  4324. X     * find the project in the gstate
  4325. X     */
  4326. X    trace(("gonzo_project_home_path_sub(gp = %08lX, name = \"%s\")\n{\n"/*}*/, gp, name->str_text));
  4327. X    gstate_data = gonzo_gstate_get(gp);
  4328. X    assert(gstate_data->where);
  4329. X    result = 0;
  4330. X    for (j = 0; j < gstate_data->where->length; ++j)
  4331. X    {
  4332. X        gstate_where    addr;
  4333. X
  4334. X        addr = gstate_data->where->list[j];
  4335. X        if (str_equal(addr->project_name, name))
  4336. X        {
  4337. X            result = addr->directory;
  4338. X            break;
  4339. X        }
  4340. X    }
  4341. X    trace(("return \"%s\";\n", (result ? result->str_text : "")));
  4342. X    trace((/*{*/"}\n"));
  4343. X    return result;
  4344. X}
  4345. X
  4346. X
  4347. Xstring_ty *
  4348. Xgonzo_project_home_path_from_name(name)
  4349. X    string_ty    *name;
  4350. X{
  4351. X    gonzo_ty    *gp;
  4352. X    size_t        j;
  4353. X    string_ty    *result;
  4354. X    string_ty    *s;
  4355. X
  4356. X    /*
  4357. X     * find the project in the gstate list
  4358. X     */
  4359. X    trace(("gonzo_project_home_path_from_name(name = \"%s\")\n{\n"/*}*/, name->str_text));
  4360. X    result = 0;
  4361. X    for (j = 0; ; ++j)
  4362. X    {
  4363. X        gp = gonzo_nth(j);
  4364. X        if (!gp)
  4365. X            break;
  4366. X        s = gonzo_project_home_path_sub(gp, name);
  4367. X        if (s)
  4368. X        {
  4369. X            result = s;
  4370. X            break;
  4371. X        }
  4372. X    }
  4373. X    trace(("return \"%s\";\n", (result ? result->str_text : "")));
  4374. X    trace((/*{*/"}\n"));
  4375. X    return result;
  4376. X}
  4377. X
  4378. X
  4379. Xvoid
  4380. Xgonzo_project_list(result)
  4381. X    wlist        *result;
  4382. X{
  4383. X    size_t        n;
  4384. X    size_t        j;
  4385. X    gonzo_ty    *gp;
  4386. X    gstate        gstate_data;
  4387. X
  4388. X    trace(("gonzo_project_list(result = %08lX)\n{\n"/*}*/, result));
  4389. X    wl_zero(result);
  4390. X    for (n = 0; ; ++n)
  4391. X    {
  4392. X        gp = gonzo_nth(n);
  4393. X        if (!gp)
  4394. X            break;
  4395. X
  4396. X        /*
  4397. X         * read the gstate file
  4398. X         */
  4399. X        gstate_data = gonzo_gstate_get(gp);
  4400. X    
  4401. X        /*
  4402. X         * list the projects
  4403. X         */
  4404. X        assert(gstate_data->where);
  4405. X        for (j = 0; j < gstate_data->where->length; ++j)
  4406. X        {
  4407. X            wl_append_unique
  4408. X            (
  4409. X                result,
  4410. X                gstate_data->where->list[j]->project_name
  4411. X            );
  4412. X        }
  4413. X    }
  4414. X    trace((/*{*/"}\n"));
  4415. X}
  4416. X
  4417. X
  4418. Xvoid
  4419. Xgonzo_project_list_user(uname, result)
  4420. X    string_ty    *uname;
  4421. X    wlist        *result;
  4422. X{
  4423. X    size_t        n;
  4424. X    size_t        j;
  4425. X
  4426. X    trace(("gonzo_project_list_user(uname = \"%s\", \
  4427. Xresult = %08lX)\n{\n"/*}*/, uname->str_text, result));
  4428. X    wl_zero(result);
  4429. X    for (n = 0; ; ++n)
  4430. X    {
  4431. X        string_ty    *ustate_path;
  4432. X        ustate        ustate_data;
  4433. X        gonzo_ty    *gp;
  4434. X
  4435. X        gp = gonzo_nth(n);
  4436. X        if (!gp)
  4437. X            break;
  4438. X
  4439. X        /*
  4440. X         * check out the ustate
  4441. X         */
  4442. X        ustate_path = str_format("%S/user/%S", gp->dir, uname);
  4443. X        trace(("ustate_path = \"%s\";\n", ustate_path->str_text));
  4444. X        gonzo_become();
  4445. X        if (!os_exists(ustate_path))
  4446. X        {
  4447. X            gonzo_become_undo();
  4448. X            str_free(ustate_path);
  4449. X            continue;
  4450. X        }
  4451. X        ustate_data = ustate_read_file(ustate_path->str_text);
  4452. X        gonzo_become_undo();
  4453. X        if (!ustate_data->own)
  4454. X            ustate_data->own =
  4455. X                (ustate_own_list)
  4456. X                ustate_own_list_type.alloc();
  4457. X        str_free(ustate_path);
  4458. X
  4459. X        /*
  4460. X         * collect all projects this user owns changes in
  4461. X         */
  4462. X        for (j = 0; j < ustate_data->own->length; ++j)
  4463. X        {
  4464. X            trace(("remember \"%s\";\n",
  4465. X                ustate_data->own->list[j]->project_name->str_text));
  4466. X            wl_append_unique
  4467. X            (
  4468. X                result,
  4469. X                ustate_data->own->list[j]->project_name
  4470. X            );
  4471. X        }
  4472. X        ustate_type.free(ustate_data);
  4473. X    }
  4474. X    trace(("found %d items\n", result->wl_nwords));
  4475. X    trace((/*{*/"}\n"));
  4476. X}
  4477. X
  4478. X
  4479. Xvoid
  4480. Xgonzo_project_add(pp)
  4481. X    project_ty    *pp;
  4482. X{
  4483. X    gstate_where    *addr_p;
  4484. X    gstate_where    addr;
  4485. X    gonzo_ty    *gp;
  4486. X    type_ty        *type_p;
  4487. X
  4488. X    trace(("gonzo_project_add(pp = %08lX)\n{\n"/*}*/, pp));
  4489. X    gp = gonzo_nth(0);
  4490. X    gstate_where_list_type.list_parse
  4491. X    (
  4492. X        gp->gstate_data->where,
  4493. X        &type_p,
  4494. X        (void **)&addr_p
  4495. X    );
  4496. X    addr = (gstate_where)gstate_where_type.alloc();
  4497. X    *addr_p = addr;
  4498. X    trace_pointer(addr);
  4499. X    addr->project_name = str_copy(project_name_get(pp));
  4500. X    addr->directory = str_copy(project_home_path_get(pp));
  4501. X    gp->modified = 1;
  4502. X    trace((/*{*/"}\n"));
  4503. X}
  4504. X
  4505. X
  4506. Xstatic int gonzo_project_delete_sub _((gonzo_ty *, project_ty *));
  4507. X
  4508. Xstatic int 
  4509. Xgonzo_project_delete_sub(gp, pp)
  4510. X    gonzo_ty    *gp;
  4511. X    project_ty    *pp;
  4512. X{
  4513. X    gstate        gstate_data;
  4514. X    size_t        j;
  4515. X    int        result;
  4516. X
  4517. X    /*
  4518. X     * find the project in the gstate
  4519. X     */
  4520. X    trace(("gonzo_project_delete_sub(gp = %08lX, pp = %08lX)\n{\n"/*}*/,
  4521. X        gp, pp));
  4522. X    gstate_data = gonzo_gstate_get(gp);
  4523. X    assert(gstate_data->where);
  4524. X    result = 0;
  4525. X    for (j = 0; j < gstate_data->where->length; ++j)
  4526. X    {
  4527. X        gstate_where    addr;
  4528. X        long        k;
  4529. X
  4530. X        addr = gstate_data->where->list[j];
  4531. X        if (!str_equal(addr->project_name, project_name_get(pp)))
  4532. X            continue;
  4533. X
  4534. X        /*
  4535. X         * delete the item from the list
  4536. X         */
  4537. X        for (k = j + 1; k < gstate_data->where->length; ++k)
  4538. X            gstate_data->where->list[k - 1] =
  4539. X                gstate_data->where->list[k];
  4540. X        gstate_data->where->length--;
  4541. X
  4542. X        /*
  4543. X         * free the item
  4544. X         */
  4545. X        gstate_where_type.free(addr);
  4546. X
  4547. X        /*
  4548. X         * mark this gstate file as modified
  4549. X         */
  4550. X        gp->modified = 1;
  4551. X        result = 1;
  4552. X        break;
  4553. X    }
  4554. X    trace(("return %d;\n", result));
  4555. X    trace((/*{*/"}\n"));
  4556. X    return result;
  4557. X}
  4558. X
  4559. X
  4560. Xvoid
  4561. Xgonzo_project_delete(pp)
  4562. X    project_ty    *pp;
  4563. X{
  4564. X    gonzo_ty    *gp;
  4565. X    long        j;
  4566. X
  4567. X    trace(("gonzo_project_delete(pp = %08lX)\n{\n"/*}*/, pp));
  4568. X    for (j = 0; ; ++j)
  4569. X    {
  4570. X        gp = gonzo_nth(j);
  4571. X        if (!gp)
  4572. X            break;
  4573. X        if (gonzo_project_delete_sub(gp, pp))
  4574. X            break;
  4575. X    }
  4576. X    trace((/*{*/"}\n"));
  4577. X}
  4578. X
  4579. X
  4580. Xvoid
  4581. Xgonzo_gstate_lock_prepare_new()
  4582. X{
  4583. X    trace(("gonzo_gstate_lock_prepare_new()\n{\n"/*}*/));
  4584. X    lock_prepare_gstate();
  4585. X    trace((/*{*/"}\n"));
  4586. X}
  4587. X
  4588. X
  4589. Xstring_ty *
  4590. Xgonzo_lockpath_get()
  4591. X{
  4592. X    static string_ty *path;
  4593. X    gonzo_ty    *gp;
  4594. X
  4595. X    trace(("gonzo_lockpath_get()\n{\n"/*}*/));
  4596. X    if (!path)
  4597. X    {
  4598. X        do_tail();
  4599. X        gp = gonzo[ngonzos - 1];
  4600. X        construct_library_directory(gp);
  4601. X        path = str_format("%S/lockfile", gp->dir);
  4602. X    }
  4603. X    trace(("return \"%s\";\n", path->str_text));
  4604. X    trace((/*{*/"}\n"));
  4605. X    return path;
  4606. X}
  4607. X
  4608. X
  4609. Xstatic int gonzo_ustate_path_sub _((gonzo_ty *, string_ty *));
  4610. X
  4611. Xstatic int
  4612. Xgonzo_ustate_path_sub(gp, project_name)
  4613. X    gonzo_ty    *gp;
  4614. X    string_ty    *project_name;
  4615. X{
  4616. X    gstate        gstate_data;
  4617. X    size_t        j;
  4618. X    int        result;
  4619. X
  4620. X    /*
  4621. X     * find the project in the gstate
  4622. X     */
  4623. X    trace(("gonzo_ustate_path_sub(gp = %08lX)\n{\n"/*}*/, gp));
  4624. X    gstate_data = gonzo_gstate_get(gp);
  4625. X    assert(gstate_data->where);
  4626. X    result = 0;
  4627. X    for (j = 0; j < gstate_data->where->length; ++j)
  4628. X    {
  4629. X        gstate_where    addr;
  4630. X
  4631. X        addr = gstate_data->where->list[j];
  4632. X        if (str_equal(addr->project_name, project_name))
  4633. X        {
  4634. X            result = 1;
  4635. X            break;
  4636. X        }
  4637. X    }
  4638. X    trace(("return %d;\n", result));
  4639. X    trace((/*{*/"}\n"));
  4640. X    return result;
  4641. X}
  4642. X
  4643. X
  4644. Xstring_ty *
  4645. Xgonzo_ustate_path(project_name, user_name)
  4646. X    string_ty    *project_name;
  4647. X    string_ty    *user_name;
  4648. X{
  4649. X    gonzo_ty    *gp;
  4650. X    size_t        j;
  4651. X    string_ty    *dir;
  4652. X    string_ty    *result;
  4653. X
  4654. X    /*
  4655. X     * find the project in the gstate list
  4656. X     *    the user state file contains an index into the project files
  4657. X     *    and is thus kept in the same directory
  4658. X     */
  4659. X    trace(("gonzo_ustate_path(project_name = \"%s\", user_name = \"%s\")\n{\n"/*}*/, project_name->str_text, user_name->str_text));
  4660. X    for (j = 0; ; ++j)
  4661. X    {
  4662. X        gp = gonzo_nth(j);
  4663. X        if (!gp)
  4664. X        {
  4665. X            fatal
  4666. X            (
  4667. X                "project \"%s\" unknown (bug)",
  4668. X                project_name->str_text
  4669. X            );
  4670. X        }
  4671. X        if (gonzo_ustate_path_sub(gp, project_name))
  4672. X            break;
  4673. X    }
  4674. X
  4675. X    /*
  4676. X     * make sure that the directory for the user state files exists
  4677. X     *    (must be world writable in testing situations)
  4678. X     */
  4679. X    gonzo_become();
  4680. X    assert(os_exists(gp->dir));
  4681. X    dir = str_format("%S/user", gp->dir);
  4682. X    if (!os_exists(dir))
  4683. X    {
  4684. X        os_mkdir(dir, 0755);
  4685. X        if (gp->temporary)
  4686. X            os_chmod(dir, 0777);
  4687. X    }
  4688. X    str_free(dir);
  4689. X    gonzo_become_undo();
  4690. X
  4691. X    /*
  4692. X     * build the user state file name
  4693. X     */
  4694. X    result = str_format("%S/user/%S", gp->dir, user_name);
  4695. X    trace(("return \"%s\";\n", result->str_text));
  4696. X    trace((/*{*/"}\n"));
  4697. X    return result;
  4698. X}
  4699. X
  4700. X
  4701. Xvoid
  4702. Xgonzo_become()
  4703. X{
  4704. X    trace(("gonzo_become()\n{\n"/*}*/));
  4705. X    user_become(gonzo_user());
  4706. X    trace((/*{*/"}\n"));
  4707. X}
  4708. X
  4709. X
  4710. Xvoid
  4711. Xgonzo_become_undo()
  4712. X{
  4713. X    trace(("gonzo_become_undo()\n{\n"/*}*/));
  4714. X    user_become_undo();
  4715. X    trace((/*{*/"}\n"));
  4716. X}
  4717. END_OF_FILE
  4718. if test 16800 -ne `wc -c <'aegis/gonzo.c'`; then
  4719.     echo shar: \"'aegis/gonzo.c'\" unpacked with wrong size!
  4720. fi
  4721. # end of 'aegis/gonzo.c'
  4722. fi
  4723. if test -f 'lib/aegis.pgm' -a "${1}" != "-c" ; then 
  4724.   echo shar: Will not clobber existing file \"'lib/aegis.pgm'\"
  4725. else
  4726. echo shar: Extracting \"'lib/aegis.pgm'\" \(16905 characters\)
  4727. sed "s/^X//" >'lib/aegis.pgm' <<'END_OF_FILE'
  4728. XP2
  4729. X#    aegis - project change supervisor
  4730. X#    Copyright (C) 1993 Peter Miller.
  4731. X#    All rights reserved.
  4732. X#
  4733. X#    This program is free software; you can redistribute it and/or modify
  4734. X#    it under the terms of the GNU General Public License as published by
  4735. X#    the Free Software Foundation; either version 2 of the License, or
  4736. X#    (at your option) any later version.
  4737. X#
  4738. X#    This program is distributed in the hope that it will be useful,
  4739. X#    but WITHOUT ANY WARRANTY; without even the implied warranty of
  4740. X#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4741. X#    GNU General Public License for more details.
  4742. X#
  4743. X#    You should have received a copy of the GNU General Public License
  4744. X#    along with this program; if not, write to the Free Software
  4745. X#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4746. X#
  4747. X# MANIFEST: portable graymap of aegis icon
  4748. X#
  4749. X64 64
  4750. X255
  4751. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4752. X255 255 255 255 255 255 223 175 112 64 64 32 32 0 0 0 16 48 80 143 175
  4753. X207 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4754. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4755. X255 255 255 255 255 255 255 255 255 255 207 96 48 12 61 97 133 169 168
  4756. X192 191 190 190 153 153 129 82 58 23 64 112 175 255 255 255 255 255 255
  4757. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4758. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 223 143 48
  4759. X37 86 159 195 194 193 192 191 191 190 189 189 188 188 187 187 186 186
  4760. X185 149 91 34 32 128 255 255 255 255 255 255 255 255 255 255 255 255
  4761. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4762. X255 255 255 255 255 239 96 32 75 148 196 195 194 193 192 191 190 190
  4763. X189 189 188 188 187 187 186 186 185 185 184 184 183 182 136 78 27 112
  4764. X239 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4765. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 143 32 87 173
  4766. X197 195 194 193 192 191 190 190 189 189 188 188 187 187 186 186 185 185
  4767. X185 184 184 183 183 182 181 180 168 66 27 143 255 255 255 255 255 255
  4768. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4769. X255 255 255 255 207 48 50 162 197 196 194 193 192 191 190 190 189 189
  4770. X188 188 187 187 186 186 185 185 185 184 184 184 183 183 182 182 181 181
  4771. X180 178 143 44 48 239 255 255 255 255 255 255 255 255 255 255 255 255
  4772. X255 255 255 255 255 255 255 255 255 255 255 255 255 159 29 125 198 196
  4773. X195 193 192 191 191 190 189 189 188 188 187 187 186 173 165 146 173 184
  4774. X184 184 183 183 183 182 182 182 181 180 180 179 178 176 98 16 159 255
  4775. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4776. X255 255 255 239 128 38 150 198 196 194 193 192 191 190 189 189 188 188
  4777. X187 187 186 186 167 183 186 163 111 136 184 183 183 183 182 182 182 181
  4778. X181 180 180 179 178 177 175 151 21 128 255 255 255 255 255 255 255 255
  4779. X255 255 255 255 255 255 255 255 255 255 255 255 239 80 38 187 197 195
  4780. X194 193 192 191 190 189 189 188 187 187 187 186 186 182 171 200 198 176
  4781. X133 56 172 183 182 182 182 181 181 181 180 180 179 179 178 177 176 175
  4782. X161 53 96 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4783. X255 255 255 239 64 75 199 197 195 194 192 191 190 190 189 188 188 187
  4784. X187 186 186 186 185 170 162 190 188 165 123 51 126 182 182 182 181 181
  4785. X181 180 180 180 179 179 178 177 177 175 174 171 52 64 239 255 255 255
  4786. X255 255 255 255 255 255 255 255 255 255 255 255 255 96 63 199 197 195
  4787. X193 192 191 190 189 189 188 188 187 187 186 186 185 185 185 177 130 159
  4788. X159 134 93 26 114 182 182 181 181 181 180 180 180 179 179 179 178 177
  4789. X177 176 175 173 159 62 96 255 255 255 255 255 255 255 255 255 255 255
  4790. X255 255 255 255 96 50 199 197 195 193 192 191 190 189 189 188 187 187
  4791. X186 186 186 185 185 185 184 184 122 102 106 84 40 36 170 182 181 181
  4792. X181 180 180 180 179 179 179 178 178 177 177 176 175 174 172 168 41 128
  4793. X255 255 255 255 255 255 255 255 255 255 255 255 255 159 38 187 197 195
  4794. X193 192 191 190 189 188 188 187 187 186 186 186 185 185 184 184 184 183
  4795. X183 127 44 35 68 148 182 181 181 181 180 180 180 179 179 179 178 178
  4796. X178 177 177 176 175 174 172 170 156 20 159 255 255 255 255 255 255 255
  4797. X255 255 255 255 223 13 175 197 195 193 192 191 190 189 188 188 187 187
  4798. X186 186 185 185 185 184 184 184 183 183 183 183 182 182 182 181 181 181
  4799. X181 180 180 180 180 179 179 179 178 178 177 177 176 176 175 174 173 171
  4800. X168 123 42 207 255 255 255 255 255 255 255 255 255 255 64 138 198 195
  4801. X193 192 191 190 184 175 181 187 187 186 186 185 185 185 184 184 184 183
  4802. X183 183 182 182 182 182 181 181 181 181 180 180 180 180 179 179 179 178
  4803. X178 178 177 168 164 176 175 174 173 172 170 166 81 64 239 255 255 255
  4804. X255 255 255 255 255 128 50 198 196 194 192 191 190 174 166 159 131 136
  4805. X186 186 185 185 185 184 184 184 183 183 183 182 182 182 182 181 181 181
  4806. X181 180 180 180 180 179 179 179 178 178 178 177 168 167 160 131 119 174
  4807. X173 172 170 168 164 40 175 255 255 255 255 255 255 255 255 16 174 196
  4808. X194 193 191 190 176 185 199 189 155 99 146 185 185 185 184 184 184 183
  4809. X183 183 182 182 182 182 181 181 181 181 180 180 180 180 179 179 179 178
  4810. X178 178 178 168 182 200 188 156 97 116 173 172 171 169 166 131 26 255
  4811. X255 255 255 255 255 255 112 62 197 195 193 191 190 189 161 189 198 185
  4812. X153 100 75 185 185 184 184 184 183 183 183 182 182 182 182 181 181 181
  4813. X181 180 180 180 180 179 179 179 179 178 178 178 177 161 189 199 185 154
  4814. X102 36 173 172 171 169 167 163 49 128 255 255 255 255 255 223 12 186
  4815. X196 193 192 191 190 189 147 169 176 164 133 79 32 185 184 184 183 183
  4816. X183 183 182 182 182 182 181 181 181 181 180 180 180 180 179 179 179 179
  4817. X178 178 178 177 177 135 168 177 163 132 79 7 173 172 171 170 168 164
  4818. X139 0 239 255 255 255 255 128 74 197 194 192 191 190 189 188 149 118
  4819. X135 123 92 33 81 184 184 183 183 183 183 182 182 182 182 181 181 181
  4820. X181 180 180 180 180 179 179 179 179 178 178 178 177 177 177 155 119 134
  4821. X122 91 34 11 173 172 171 170 168 165 161 48 143 255 255 255 255 48 173
  4822. X195 193 191 190 189 188 188 187 120 63 55 24 36 161 184 183 183 183 183
  4823. X182 182 182 182 181 181 181 181 180 180 180 180 179 179 179 179 178 178
  4824. X178 178 177 177 177 176 119 58 54 25 12 130 173 172 171 170 168 166 162
  4825. X117 32 255 255 255 175 50 196 194 192 191 189 189 188 187 186 186 151
  4826. X116 138 184 184 183 183 183 183 182 182 182 181 181 181 181 181 180 180
  4827. X180 180 179 179 179 179 178 178 178 178 177 177 177 176 176 176 164 109
  4828. X120 163 173 173 172 171 170 169 167 163 158 29 159 255 255 112 123 195
  4829. X193 191 190 189 188 187 187 186 186 185 185 184 184 184 183 183 183 182
  4830. X182 182 181 181 181 181 181 180 180 180 180 179 179 179 179 178 178 178
  4831. X178 177 177 177 177 176 176 176 175 175 174 174 173 173 172 171 170 169
  4832. X167 164 159 76 96 255 255 32 147 194 192 190 189 188 187 187 186 186
  4833. X185 185 184 184 184 183 183 183 182 182 182 181 181 181 181 181 180 180
  4834. X180 180 179 179 179 179 178 178 178 178 177 177 177 177 176 176 176 175
  4835. X175 175 174 174 173 172 172 171 170 169 167 164 160 125 32 255 239 25
  4836. X195 193 191 190 189 188 187 186 186 185 185 184 184 184 183 183 183 182
  4837. X182 182 181 181 181 181 180 180 180 180 180 179 179 179 179 178 178 178
  4838. X178 177 177 177 177 176 176 176 175 175 175 174 174 173 173 172 172 171
  4839. X170 168 167 165 161 145 18 239 175 73 194 192 190 189 188 187 187 186
  4840. X185 185 184 184 184 183 183 183 182 182 182 181 181 181 181 180 180 180
  4841. X180 180 179 179 179 179 178 178 178 178 177 177 177 177 176 176 176 176
  4842. X175 175 175 174 174 173 173 172 171 171 170 168 167 165 162 155 55 175
  4843. X128 110 193 191 190 189 188 187 186 186 185 185 184 184 183 183 183 182
  4844. X182 182 181 181 181 181 180 180 180 180 180 179 179 179 179 178 178 178
  4845. X178 178 177 177 177 177 176 176 176 175 175 175 174 174 173 173 172 172
  4846. X171 170 169 168 167 165 162 156 74 143 112 146 192 190 189 188 187 186
  4847. X186 185 185 184 184 183 183 183 182 182 182 182 181 181 181 180 180 180
  4848. X180 180 179 179 179 179 178 178 178 178 178 177 177 177 177 176 176 176
  4849. X175 175 175 174 174 174 173 173 172 172 171 170 169 168 167 165 162 157
  4850. X94 64 16 145 191 190 188 188 187 186 185 185 184 184 183 183 183 182
  4851. X182 182 182 181 181 181 180 180 180 180 180 179 179 179 179 171 174 178
  4852. X178 178 177 177 177 177 176 176 176 176 175 175 175 174 174 173 173 172
  4853. X172 171 171 170 169 168 166 164 162 157 130 64 32 156 191 189 188 187
  4854. X186 186 185 184 184 184 183 183 182 182 182 182 181 181 181 181 180 180
  4855. X180 180 179 179 179 172 166 168 146 123 163 177 177 177 177 176 176 176
  4856. X176 175 175 175 174 174 174 173 173 172 172 171 170 170 169 168 166 164
  4857. X161 157 139 0 32 192 190 189 188 187 186 185 185 184 184 183 183 183
  4858. X182 182 182 181 181 181 181 180 180 180 180 179 179 179 179 166 197 197
  4859. X173 131 67 177 177 177 176 176 176 176 175 175 175 174 174 174 173 173
  4860. X172 172 171 171 170 169 168 167 166 164 161 157 139 0 0 191 189 188 187
  4861. X186 186 185 184 184 183 183 183 182 182 182 181 181 181 181 180 180 180
  4862. X180 179 179 179 179 163 167 197 194 172 131 58 122 177 176 176 176 176
  4863. X175 175 175 175 174 174 173 173 173 172 172 171 171 170 169 168 167 165
  4864. X164 161 156 148 0 0 190 189 188 187 186 185 185 184 184 183 183 182 182
  4865. X182 181 181 181 181 180 180 180 180 179 179 179 179 178 170 145 174 172
  4866. X150 107 37 110 176 176 176 176 175 175 175 175 174 174 174 173 173 172
  4867. X172 171 171 170 170 169 168 167 165 163 160 156 147 0 0 178 188 187 186
  4868. X185 185 184 184 169 168 182 182 182 181 181 181 181 180 180 180 180 179
  4869. X179 179 179 178 178 178 107 130 130 107 65 7 143 176 176 176 175 175
  4870. X175 175 174 174 174 173 173 173 172 172 171 171 164 162 168 167 166 165
  4871. X163 160 155 137 0 32 153 188 187 186 185 184 181 166 171 155 115 139
  4872. X181 181 181 181 180 180 180 180 179 179 179 179 178 178 178 178 162 67
  4873. X57 38 10 55 176 176 176 175 175 175 175 174 174 174 173 173 173 172 172
  4874. X171 167 168 169 142 109 148 166 164 162 159 154 127 0 48 141 187 186
  4875. X185 185 184 168 195 199 181 140 75 181 181 181 180 180 180 180 179 179
  4876. X179 179 178 178 178 178 178 177 166 111 121 132 176 176 176 175 175 175
  4877. X175 174 174 174 174 173 173 172 172 172 171 168 199 195 169 122 73 165
  4878. X164 161 158 153 117 48 64 129 187 186 185 184 184 156 195 195 176 139
  4879. X74 126 181 180 180 180 180 179 179 179 179 178 178 178 178 178 177 177
  4880. X177 177 176 176 176 176 175 175 175 175 174 174 174 174 173 173 173 172
  4881. X172 171 162 177 197 191 166 120 46 113 163 161 157 151 89 80 143 93 186
  4882. X185 185 184 183 136 173 172 153 116 50 102 180 180 180 180 179 179 179
  4883. X179 178 178 178 178 178 177 177 177 177 176 176 176 176 175 175 175 175
  4884. X174 174 174 174 173 173 173 172 172 171 171 151 154 176 170 142 98 25
  4885. X92 162 160 156 149 70 128 159 70 186 185 184 184 183 118 125 131 112 73
  4886. X12 124 180 180 180 179 179 179 179 178 178 178 178 177 177 177 177 177
  4887. X176 176 176 176 175 175 175 175 174 174 174 174 173 173 173 172 172 171
  4888. X171 171 164 104 131 128 102 53 5 112 161 159 154 147 35 175 207 23 185
  4889. X184 184 183 183 182 75 56 39 10 68 180 180 180 179 179 179 179 178 178
  4890. X178 178 177 177 177 177 177 176 176 176 176 175 175 175 175 174 174 174
  4891. X174 173 173 173 172 172 172 171 171 170 170 138 67 57 32 4 41 163 160
  4892. X157 153 143 0 207 255 32 149 184 183 183 182 182 181 136 102 124 180
  4893. X180 180 179 179 179 179 178 178 178 178 177 177 177 177 177 176 176 176
  4894. X176 175 175 175 175 174 174 174 174 173 173 173 172 172 172 171 171 170
  4895. X170 169 169 168 125 83 113 163 162 159 156 150 115 32 255 255 128 91
  4896. X183 183 182 182 182 181 181 180 180 180 180 179 179 179 179 178 178 178
  4897. X178 177 177 177 177 176 176 176 176 176 175 175 175 175 174 174 174 174
  4898. X173 173 173 172 172 172 171 171 170 170 169 169 168 167 166 165 164 163
  4899. X161 158 154 147 69 128 255 255 223 34 182 182 182 182 181 181 180 180
  4900. X180 180 179 179 179 178 178 178 178 178 177 177 177 177 176 176 176 176
  4901. X176 175 175 175 175 174 174 174 174 173 173 173 172 172 172 171 171 170
  4902. X170 169 169 168 168 167 166 165 163 162 160 156 152 143 17 223 255 255
  4903. X255 48 124 181 181 181 181 180 180 180 179 179 179 179 178 178 178 178
  4904. X177 177 177 177 177 176 176 176 176 175 175 175 175 175 174 174 174 174
  4905. X173 173 173 172 172 172 171 171 171 170 170 169 168 168 167 166 165 164
  4906. X162 161 158 154 149 113 16 255 255 255 255 143 67 180 181 181 180 180
  4907. X180 179 179 179 179 178 178 178 178 177 177 177 177 177 176 176 176 176
  4908. X175 175 175 175 175 174 174 174 174 173 173 173 172 172 172 171 171 171
  4909. X170 170 169 168 168 167 166 165 164 163 161 159 156 152 144 51 143 255
  4910. X255 255 255 255 0 157 180 180 180 179 179 179 179 178 178 178 178 178
  4911. X177 177 177 177 176 176 176 176 176 175 175 175 175 174 174 174 174 173
  4912. X173 173 173 172 172 172 171 171 171 170 170 169 169 168 167 167 166 165
  4913. X163 162 160 158 154 149 121 16 255 255 255 255 255 255 128 66 178 179
  4914. X179 179 179 179 178 178 178 178 177 177 177 177 177 176 176 176 176 175
  4915. X175 175 175 175 174 174 174 174 173 173 173 173 172 172 172 171 171 170
  4916. X170 170 169 169 168 167 167 166 165 164 162 161 158 156 151 144 51 96
  4917. X255 255 255 255 255 255 239 32 143 178 178 178 178 178 178 178 177 177
  4918. X177 177 177 176 176 176 176 176 175 175 175 175 174 174 174 174 173 173
  4919. X173 173 172 172 172 171 171 171 170 170 170 169 169 168 167 167 166 165
  4920. X164 163 161 159 157 153 147 121 24 239 255 255 255 255 255 255 255 159
  4921. X44 176 177 177 177 177 177 177 177 177 177 176 176 176 176 176 175 175
  4922. X175 175 175 174 174 174 174 173 173 173 173 172 172 172 171 171 171 170
  4923. X170 169 169 169 168 167 167 166 165 164 163 161 160 157 154 150 141 33
  4924. X128 255 255 255 255 255 255 255 255 255 48 98 175 176 177 177 177 177
  4925. X176 176 176 176 176 176 175 169 158 143 135 152 174 174 174 173 173 173
  4926. X173 172 172 172 172 171 171 171 162 164 157 135 129 168 167 167 166 165
  4927. X164 163 162 160 158 155 151 144 77 80 255 255 255 255 255 255 255 255
  4928. X255 255 223 0 151 175 175 176 176 176 176 176 176 175 175 175 170 188
  4929. X197 180 145 66 164 173 173 173 173 172 172 172 172 171 171 171 170 167
  4930. X171 196 191 161 108 123 167 166 165 164 163 162 160 158 155 152 146 128
  4931. X16 207 255 255 255 255 255 255 255 255 255 255 255 159 21 161 174 175
  4932. X175 175 175 175 175 175 175 175 165 194 199 181 147 85 104 173 173 172
  4933. X172 172 172 171 171 171 171 170 170 161 184 200 191 164 119 33 155 165
  4934. X164 163 162 160 158 156 152 148 121 17 159 255 255 255 255 255 255 255
  4935. X255 255 255 255 255 255 112 63 171 173 174 174 174 174 174 174 174 174
  4936. X132 176 180 162 126 70 67 172 172 172 172 171 171 171 171 170 170 170
  4937. X169 155 165 181 172 146 99 21 123 164 163 161 160 158 156 153 147 139
  4938. X33 128 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 80
  4939. X53 170 172 173 173 173 173 173 173 173 130 136 140 125 89 29 64 172 172
  4940. X171 171 171 171 170 170 170 169 169 168 148 119 144 136 107 59 2 133
  4941. X162 161 160 158 155 152 148 140 42 80 239 255 255 255 255 255 255 255
  4942. X255 255 255 255 255 255 255 255 255 64 62 158 170 171 172 172 172 172
  4943. X172 156 104 78 62 25 1 150 171 171 171 170 170 170 170 169 169 168 168
  4944. X168 167 124 70 69 42 7 30 162 161 159 157 155 152 147 131 42 80 239 255
  4945. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 64
  4946. X41 156 169 170 171 171 171 171 171 160 86 66 75 128 171 170 170 170 170
  4947. X169 169 169 168 168 168 167 167 166 165 134 52 41 71 151 160 159 157
  4948. X154 151 146 114 42 64 255 255 255 255 255 255 255 255 255 255 255 255
  4949. X255 255 255 255 255 255 255 255 255 112 31 133 167 168 169 169 170 170
  4950. X170 170 170 170 170 170 169 169 169 169 168 168 168 167 167 167 166 165
  4951. X165 164 163 163 162 161 159 158 156 153 150 144 112 16 128 255 255 255
  4952. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4953. X255 255 143 16 91 164 166 167 168 168 168 169 169 169 168 168 168 168
  4954. X168 167 167 167 167 166 166 165 165 164 163 163 162 161 159 158 156 154
  4955. X151 148 141 76 40 143 255 255 255 255 255 255 255 255 255 255 255 255
  4956. X255 255 255 255 255 255 255 255 255 255 255 255 255 223 48 40 131 163
  4957. X164 165 166 167 167 167 167 167 167 167 166 166 166 165 165 165 164 164
  4958. X163 162 161 160 159 158 156 154 152 148 143 104 42 64 239 255 255 255
  4959. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4960. X255 255 255 255 255 255 255 175 0 69 129 161 163 164 164 164 165 165
  4961. X165 165 164 164 164 164 163 163 162 161 160 160 159 157 156 154 152 149
  4962. X144 130 51 16 143 255 255 255 255 255 255 255 255 255 255 255 255 255
  4963. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4964. X223 128 10 49 127 157 159 160 161 161 162 162 162 161 161 161 160 160
  4965. X159 158 157 156 154 153 150 147 143 113 51 16 128 223 255 255 255 255
  4966. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4967. X255 255 255 255 255 255 255 255 255 255 255 255 239 143 32 29 76 116
  4968. X154 155 156 157 157 157 157 156 156 155 154 153 151 150 147 144 106 77
  4969. X17 16 128 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4970. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4971. X255 255 255 255 255 255 255 223 112 32 19 55 74 93 112 139 148 148 147
  4972. X146 136 125 98 71 52 17 32 112 191 255 255 255 255 255 255 255 255 255
  4973. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4974. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4975. X207 159 112 80 48 32 48 0 0 0 32 48 64 128 175 223 255 255 255 255 255
  4976. X255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
  4977. X255
  4978. END_OF_FILE
  4979. if test 16905 -ne `wc -c <'lib/aegis.pgm'`; then
  4980.     echo shar: \"'lib/aegis.pgm'\" unpacked with wrong size!
  4981. fi
  4982. # end of 'lib/aegis.pgm'
  4983. fi
  4984. if test -f 'test/00/t0002a.sh' -a "${1}" != "-c" ; then 
  4985.   echo shar: Will not clobber existing file \"'test/00/t0002a.sh'\"
  4986. else
  4987. echo shar: Extracting \"'test/00/t0002a.sh'\" \(14483 characters\)
  4988. sed "s/^X//" >'test/00/t0002a.sh' <<'END_OF_FILE'
  4989. X#! /bin/sh
  4990. X#
  4991. X#    aegis - project change supervisor
  4992. X#    Copyright (C) 1991, 1992, 1993 Peter Miller.
  4993. X#    All rights reserved.
  4994. X#
  4995. X#    This program is free software; you can redistribute it and/or modify
  4996. X#    it under the terms of the GNU General Public License as published by
  4997. X#    the Free Software Foundation; either version 2 of the License, or
  4998. X#    (at your option) any later version.
  4999. X#
  5000. X#    This program is distributed in the hope that it will be useful,
  5001. X#    but WITHOUT ANY WARRANTY; without even the implied warranty of
  5002. X#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5003. X#    GNU General Public License for more details.
  5004. X#
  5005. X#    You should have received a copy of the GNU General Public License
  5006. X#    along with this program; if not, write to the Free Software
  5007. X#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5008. X#
  5009. X# MANIFEST: Test core functionality.
  5010. X#
  5011. X
  5012. Xunset AEGIS_PROJECT
  5013. Xunset AEGIS_CHANGE
  5014. Xumask 022
  5015. X
  5016. XUSER=${USER:-${LOGNAME:-`whoami`}}
  5017. X
  5018. Xwork=${AEGIS_TMP:-/tmp}/$$
  5019. X
  5020. Xfail()
  5021. X{
  5022. X    set +x
  5023. X    echo FAILED test of core functionality 1>&2
  5024. X    find $work -type d -user $USER -exec chmod u+w {} \;
  5025. X    rm -rf $work
  5026. X    exit 1
  5027. X}
  5028. Xpass()
  5029. X{
  5030. X    set +x
  5031. X    echo PASSED 1>&2
  5032. X    find $work -type d -user $USER -exec chmod u+w {} \;
  5033. X    rm -rf $work
  5034. X    exit 0
  5035. X}
  5036. Xtrap "fail" 1 2 3 15
  5037. X
  5038. X#
  5039. X# some variable to make things earier to read
  5040. X#
  5041. XPAGER=cat
  5042. Xexport PAGER
  5043. Xworklib=$work/lib
  5044. Xworkproj=$work/foo.proj
  5045. Xworkchan=$work/foo.chan
  5046. Xtmp=$work/tmp
  5047. X
  5048. X#
  5049. X# make the directories
  5050. X#
  5051. Xmkdir $work
  5052. Xif test $? -ne 0 ; then exit 1; fi
  5053. X
  5054. X#
  5055. X# make a new project
  5056. X#    and check files it should have made
  5057. X#
  5058. X./bin/aegis -newpro foo -dir $workproj -lib $worklib
  5059. Xif test $? -ne 0 ; then fail; fi
  5060. X./bin/aegis -newpro -list -lib $worklib
  5061. Xif test $? -ne 0 ; then fail; fi
  5062. Xif test ! -r $worklib/state ; then fail; fi
  5063. Xif test ! -r $workproj/info/state ; then fail; fi
  5064. X
  5065. X#
  5066. X# change project attributes
  5067. X#
  5068. Xcat > $tmp << 'end'
  5069. Xdescription = "A bogus project created to test things.";
  5070. Xdeveloper_may_review = true;
  5071. Xdeveloper_may_integrate = true;
  5072. Xreviewer_may_integrate = true;
  5073. Xend
  5074. X./bin/aegis -proatt -list --proj=foo -lib $worklib
  5075. Xif test $? -ne 0 ; then fail; fi
  5076. X./bin/aegis -proatt $tmp -proj foo -lib $worklib
  5077. Xif test $? -ne 0 ; then fail; fi
  5078. X
  5079. X#
  5080. X# create a new change
  5081. X#    make sure it creates the files it should
  5082. X#
  5083. Xcat > $tmp << 'end'
  5084. Xbrief_description = "This change is used to test the aegis functionality \
  5085. Xwith respect to change descriptions.";
  5086. Xcause = internal_bug;
  5087. Xend
  5088. X./bin/aegis -newcha -list -pro foo -lib $worklib
  5089. Xif test $? -ne 0 ; then fail; fi
  5090. X./bin/aegis -new_change $tmp -project foo -lib $worklib
  5091. Xif test $? -ne 0 ; then fail; fi
  5092. Xif test ! -r $workproj/info/state ; then fail; fi
  5093. Xif test ! -r $workproj/info/change/0/001 ; then fail; fi
  5094. X
  5095. X#
  5096. X# create a second change
  5097. X#    make sure it creates the files it should
  5098. X#
  5099. Xcat > $tmp << 'end'
  5100. Xbrief_description = "This change was added to make the various listings \
  5101. Xmuch more interesting.";
  5102. Xcause = internal_bug;
  5103. Xend
  5104. X./bin/aegis -new_change $tmp -project foo -lib $worklib
  5105. Xif test $? -ne 0 ; then fail; fi
  5106. X./bin/aegis -new_change -list -project foo -lib $worklib
  5107. Xif test $? -ne 0 ; then fail; fi
  5108. X
  5109. X#
  5110. X# add a new developer
  5111. X#
  5112. X./bin/aegis -newdev -list -pr foo -lib $worklib
  5113. Xif test $? -ne 0 ; then fail; fi
  5114. X./bin/aegis -newdev $USER -p foo -lib $worklib
  5115. Xif test $? -ne 0 ; then fail; fi
  5116. X./bin/aegis -newdev -list -pr foo -lib $worklib
  5117. Xif test $? -ne 0 ; then fail; fi
  5118. X
  5119. X#
  5120. X# begin development of a change
  5121. X#    check it made the files it should
  5122. X#
  5123. X./bin/aegis -devbeg -list -project foo -lib $worklib
  5124. Xif test $? -ne 0 ; then fail; fi
  5125. X./bin/aegis -devbeg 1 -p foo -dir $workchan -lib $worklib
  5126. Xif test $? -ne 0 ; then fail; fi
  5127. Xif test ! -r $workproj/info/change/0/001 ; then fail; fi
  5128. Xif test ! -r $worklib/user/$USER ; then fail; fi
  5129. X./bin/aegis -new_change -list -project foo -lib $worklib
  5130. Xif test $? -ne 0 ; then fail; fi
  5131. X
  5132. X#
  5133. X# add a new files to the change
  5134. X#
  5135. X./bin/aegis -new_file -list -lib $worklib -proJ foo
  5136. Xif test $? -ne 0 ; then fail; fi
  5137. X./bin/aegis -new_file $workchan/main.c -nl -lib $worklib -Pro foo
  5138. Xif test $? -ne 0 ; then fail; fi
  5139. X./bin/aegis -new_file $workchan/config -nl -lib $worklib -p foo
  5140. Xif test $? -ne 0 ; then fail; fi
  5141. Xif test ! -r $workproj/info/change/0/001 ; then fail; fi
  5142. X./bin/aegis -new_file -list -lib $worklib -p foo
  5143. Xif test $? -ne 0 ; then fail; fi
  5144. Xcat > $workchan/main.c << 'end'
  5145. Xvoid
  5146. Xmain()
  5147. X{
  5148. X    exit(0);
  5149. X}
  5150. Xend
  5151. Xcat > $workchan/config << 'end'
  5152. Xbuild_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  5153. X
  5154. Xhistory_get_command =
  5155. X    "co -u'$e' -p $h,v > $o";
  5156. Xhistory_create_command =
  5157. X    "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  5158. Xhistory_put_command =
  5159. X    "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  5160. Xhistory_query_command =
  5161. X    "rlog -r $h,v | awk '/^head:/ {print $$2}'";
  5162. X
  5163. Xdiff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  5164. X
  5165. Xdiff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
  5166. X    echo '1,$$p' ) | ed - $mr > $out";
  5167. X
  5168. X/*
  5169. X * file templates
  5170. X */
  5171. Xfile_template =
  5172. X[
  5173. X    {
  5174. X        pattern = [ "*" ];
  5175. X        body = "hello\n";
  5176. X    },
  5177. X    {
  5178. X        pattern = [ "test/*/*.sh" ];
  5179. X        body = "#!/bin/sh\nexit 1\n";
  5180. X    }
  5181. X];
  5182. Xend
  5183. X
  5184. X#
  5185. X# create a new test
  5186. X#
  5187. X./bin/aegis -nt -l -lib $worklib -p foo
  5188. Xif test $? -ne 0 ; then fail; fi
  5189. X./bin/aegis -nt -lib $worklib -p foo
  5190. Xif test $? -ne 0 ; then fail; fi
  5191. Xcat > $workchan/test/00/t0001a.sh << 'end'
  5192. X#!/bin/sh
  5193. X#
  5194. X# Project: "foo"
  5195. X# Change: 1
  5196. X#
  5197. X
  5198. Xfail()
  5199. X{
  5200. X    echo SHUZBUTT 1>&2
  5201. X    exit 1
  5202. X}
  5203. Xpass()
  5204. X{
  5205. X    exit 0
  5206. X}
  5207. Xtrap "fail" 1 2 3 15
  5208. X
  5209. X./foo
  5210. Xq=$?
  5211. X
  5212. X# check for signals
  5213. Xif test $q -ge 128 
  5214. Xthen
  5215. X    fail
  5216. Xfi
  5217. X
  5218. X# should not complain
  5219. Xif test $q -ne 0 
  5220. Xthen
  5221. X    fail
  5222. Xfi
  5223. X
  5224. X# it probably worked
  5225. Xpass
  5226. Xend
  5227. X
  5228. X#
  5229. X# let the clock tick over, so the build will be happy
  5230. X#
  5231. Xsleep 1
  5232. X
  5233. X#
  5234. X# build the change
  5235. X#
  5236. X./bin/aegis -build -list -lib $worklib -p foo
  5237. Xif test $? -ne 0 ; then fail; fi
  5238. X./bin/aegis -build -nl -lib $worklib -p foo
  5239. Xif test $? -ne 0 ; then fail; fi
  5240. Xif test ! -r $workproj/info/change/0/001 ; then fail; fi
  5241. X
  5242. X#
  5243. X# difference the change
  5244. X#
  5245. X./bin/aegis -diff -list -lib $worklib -p foo
  5246. Xif test $? -ne 0 ; then fail; fi
  5247. X./bin/aegis -diff -lib $worklib -p foo
  5248. Xif test $? -ne 0 ; then fail; fi
  5249. X
  5250. X#
  5251. X# test the change
  5252. X#
  5253. X./bin/aegis -test -l -lib $worklib -p foo
  5254. Xif test $? -ne 0 ; then fail; fi
  5255. X./bin/aegis -test -lib $worklib -p foo
  5256. Xif test $? -ne 0 ; then fail; fi
  5257. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5258. X
  5259. X#
  5260. X# finish development of the change
  5261. X#
  5262. X./bin/aegis -dev_end -list -lib $worklib -p foo
  5263. Xif test $? -ne 0 ; then fail; fi
  5264. X./bin/aegis -dev_end -lib $worklib -p foo
  5265. Xif test $? -ne 0 ; then fail; fi
  5266. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5267. Xif test ! -r $workproj/info/state ; then fail ; fi
  5268. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5269. X
  5270. X#
  5271. X# add a new reviewer
  5272. X#
  5273. X./bin/aegis -newrev -list -pr foo -lib $worklib
  5274. Xif test $? -ne 0 ; then fail; fi
  5275. X./bin/aegis -newrev $USER -p foo -lib $worklib
  5276. Xif test $? -ne 0 ; then fail; fi
  5277. X./bin/aegis -newrev -list -pr foo -lib $worklib
  5278. Xif test $? -ne 0 ; then fail; fi
  5279. X
  5280. X#
  5281. X# fail the review
  5282. X#
  5283. X./bin/aegis -review_fail -list -p foo -lib $worklib
  5284. Xif test $? -ne 0 ; then fail; fi
  5285. Xcat > $tmp << 'end'
  5286. XThis is a failed review comment.
  5287. Xend
  5288. X./bin/aegis -review_fail $tmp -chan 1 -proj foo -lib $worklib
  5289. Xif test $? -ne 0 ; then fail; fi
  5290. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5291. Xif test ! -r $workproj/info/state ; then fail ; fi
  5292. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5293. X
  5294. X#
  5295. X# build the change again
  5296. X# and difference
  5297. X# and test
  5298. X# end finish, again
  5299. X#
  5300. Xsleep 1
  5301. X./bin/aegis -build -nl -lib $worklib -p foo
  5302. Xif test $? -ne 0 ; then fail; fi
  5303. X./bin/aegis -diff -nl -lib $worklib -p foo
  5304. Xif test $? -ne 0 ; then fail; fi
  5305. X./bin/aegis -test -nl -lib $worklib -p foo
  5306. Xif test $? -ne 0 ; then fail; fi
  5307. X./bin/aegis -dev_end -lib $worklib -p foo
  5308. Xif test $? -ne 0 ; then fail; fi
  5309. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5310. Xif test ! -r $workproj/info/state ; then fail ; fi
  5311. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5312. X
  5313. X#
  5314. X# pass the review
  5315. X#
  5316. X./bin/aegis -review_pass -list -proj foo -lib $worklib
  5317. Xif test $? -ne 0 ; then fail; fi
  5318. X./bin/aegis -review_pass -chan 1 -proj foo -lib $worklib
  5319. Xif test $? -ne 0 ; then fail; fi
  5320. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5321. Xif test ! -r $workproj/info/state ; then fail ; fi
  5322. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5323. X
  5324. X#
  5325. X# add an integrator
  5326. X#
  5327. X./bin/aegis -newint -list -pr foo -lib $worklib
  5328. Xif test $? -ne 0 ; then fail; fi
  5329. X./bin/aegis -newint $USER -p foo -lib $worklib
  5330. Xif test $? -ne 0 ; then fail; fi
  5331. X./bin/aegis -newint -list -pr foo -lib $worklib
  5332. Xif test $? -ne 0 ; then fail; fi
  5333. X
  5334. X#
  5335. X# start integrating
  5336. X#
  5337. X./bin/aegis -intbeg -l -p foo -lib $worklib
  5338. Xif test $? -ne 0 ; then fail; fi
  5339. X./bin/aegis -intbeg 1 -p foo -lib $worklib
  5340. Xif test $? -ne 0 ; then fail; fi
  5341. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5342. Xif test ! -r $workproj/info/state ; then fail ; fi
  5343. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5344. X./bin/aegis -integrate_begin_undo -l -lib $worklib -p foo
  5345. Xif test $? -ne 0 ; then fail; fi
  5346. X
  5347. X#
  5348. X# make sure -chdir works
  5349. X#
  5350. X./bin/aegis -cd -l -lib $worklib -p foo
  5351. Xif test $? -ne 0 ; then fail; fi
  5352. Xdir=`./bin/aegis -cd fred -bl -p foo -lib $worklib`
  5353. Xif test $? -ne 0 ; then fail; fi
  5354. Xif test $dir != $workproj/baseline/fred ; then fail; fi
  5355. Xdir=`./bin/aegis -cd -dd -p foo -c 1 fred -lib $worklib`
  5356. Xif test $? -ne 0 ; then fail; fi
  5357. Xif test $dir != $workchan/fred ; then fail; fi
  5358. Xdir=`./bin/aegis -cd -p foo -c 1 fred -lib $worklib`
  5359. Xif test $? -ne 0 ; then fail; fi
  5360. Xif test $dir != $workproj/delta.001/fred ; then fail; fi
  5361. X
  5362. X#
  5363. X# integrate build
  5364. X#
  5365. X./bin/aegis -build -l -lib $worklib -p foo
  5366. Xif test $? -ne 0 ; then fail; fi
  5367. Xsleep 1
  5368. X./bin/aegis -build -nl -lib $worklib -p foo
  5369. Xif test $? -ne 0 ; then fail; fi
  5370. X./bin/aegis -test -nl -lib $worklib -p foo
  5371. Xif test $? -ne 0 ; then fail; fi
  5372. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5373. Xif test -f $workproj/delta.001/aegis.log ; then fail; fi
  5374. X
  5375. X#
  5376. X# fail the integration
  5377. X#
  5378. X./bin/aegis -intfail -l -lib $worklib -p foo
  5379. Xif test $? -ne 0 ; then fail; fi
  5380. Xcat > $tmp << 'end'
  5381. XThis is a failed integration comment.
  5382. Xend
  5383. X./bin/aegis -intfail $tmp -lib $worklib -p foo
  5384. Xif test $? -ne 0 ; then fail; fi
  5385. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5386. Xif test ! -r $workproj/info/state ; then fail ; fi
  5387. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5388. X
  5389. X
  5390. X#
  5391. X# build the change again
  5392. X# and difference
  5393. X# and test
  5394. X# and finish, again
  5395. X# and review pass again
  5396. X# and start integrating again
  5397. X#
  5398. Xsleep 1
  5399. X./bin/aegis -build -nl -lib $worklib -p foo
  5400. Xif test $? -ne 0 ; then fail; fi
  5401. X./bin/aegis -diff -nl -lib $worklib -p foo
  5402. Xif test $? -ne 0 ; then fail; fi
  5403. X./bin/aegis -test -nl -lib $worklib -p foo
  5404. Xif test $? -ne 0 ; then fail; fi
  5405. X./bin/aegis -dev_end -lib $worklib -p foo
  5406. Xif test $? -ne 0 ; then fail; fi
  5407. X./bin/aegis -review_pass -chan 1 -proj foo -lib $worklib
  5408. Xif test $? -ne 0 ; then fail; fi
  5409. X./bin/aegis -intbeg 1 -p foo -lib $worklib
  5410. Xif test $? -ne 0 ; then fail; fi
  5411. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5412. Xif test ! -r $workproj/info/state ; then fail ; fi
  5413. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5414. X
  5415. X#
  5416. X# build and test the integration
  5417. X#
  5418. Xsleep 1
  5419. X./bin/aegis -build -nl -lib $worklib -p foo
  5420. Xif test $? -ne 0 ; then fail; fi
  5421. X./bin/aegis -test -nl -lib $worklib -p foo
  5422. Xif test $? -ne 0 ; then fail; fi
  5423. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5424. X
  5425. X#
  5426. X# pass the integration
  5427. X#
  5428. X./bin/aegis -intpass -l -lib $worklib -p foo
  5429. Xif test $? -ne 0 ; then fail; fi
  5430. X./bin/aegis -intpass -nl -lib $worklib -p foo
  5431. Xif test $? -ne 0 ; then fail; fi
  5432. Xif test ! -r $workproj/info/change/0/001 ; then fail ; fi
  5433. Xif test ! -r $workproj/info/state ; then fail ; fi
  5434. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5435. X
  5436. X#
  5437. X# check out the listings
  5438. X#
  5439. X./bin/aegis -list -list -lib $worklib
  5440. Xif test $? -ne 0 ; then fail; fi
  5441. X./bin/aegis -list chahist -c 1 -p foo -lib $worklib
  5442. Xif test $? -ne 0 ; then fail; fi
  5443. X
  5444. X#
  5445. X# start work on change 2
  5446. X#
  5447. X./bin/aegis -devbeg 2 -p foo -dir $workchan -lib $worklib
  5448. Xif test $? -ne 0 ; then fail; fi
  5449. X./bin/aegis -cp -l -lib $worklib -p foo
  5450. Xif test $? -ne 0 ; then fail; fi
  5451. X
  5452. X#
  5453. X# copy a file into the change
  5454. X#
  5455. X./bin/aegis -cp $workchan/main.c -nl -lib $worklib -p foo
  5456. Xif test $? -ne 0 ; then fail; fi
  5457. Xif test ! -r $workproj/info/change/0/002 ; then fail ; fi
  5458. Xif test ! -r $workproj/info/state ; then fail ; fi
  5459. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5460. X
  5461. X#
  5462. X# change the file
  5463. X#
  5464. Xcat > $workchan/main.c << 'end'
  5465. X
  5466. X#include <stdio.h>
  5467. X
  5468. Xvoid
  5469. Xmain(argc, argv)
  5470. X    int    argc;
  5471. X    char    **argv;
  5472. X{
  5473. X    if (argc != 1)
  5474. X    {
  5475. X        fprintf(stderr, "usage: %s\n", argv[0]);
  5476. X        exit(1);
  5477. X    }
  5478. X    printf("hello, world\n");
  5479. X    exit(0);
  5480. X}
  5481. Xend
  5482. X
  5483. X#
  5484. X# need another test
  5485. X#
  5486. X./bin/aegis -nt -lib $worklib -p foo
  5487. Xif test $? -ne 0 ; then fail; fi
  5488. Xcat > $workchan/test/00/t0002a.sh << 'end'
  5489. X#!/bin/sh
  5490. X#
  5491. X# Project: "foo"
  5492. X# Change: 2
  5493. X#
  5494. X
  5495. Xfail()
  5496. X{
  5497. X    echo SHUZBUTT 1>&2
  5498. X    exit 1
  5499. X}
  5500. Xpass()
  5501. X{
  5502. X    exit 0
  5503. X}
  5504. Xtrap "fail" 1 2 3 15
  5505. X
  5506. X./foo ickky
  5507. Xq=$?
  5508. X
  5509. X# check for signals
  5510. Xif test $q -ge 128 
  5511. Xthen
  5512. X    fail
  5513. Xfi
  5514. X
  5515. X# should have complained
  5516. Xif test $q -eq 0 
  5517. Xthen
  5518. X    fail
  5519. Xfi
  5520. X
  5521. X# it probably worked
  5522. Xpass
  5523. Xend
  5524. X
  5525. X#
  5526. X# tick over clock to keep build happy
  5527. X#
  5528. Xsleep 1
  5529. X
  5530. X#
  5531. X# build the change
  5532. X# diff the change
  5533. X# test the change
  5534. X#
  5535. X./bin/aegis -b -nl -lib $worklib -p foo
  5536. Xif test $? -ne 0 ; then fail; fi
  5537. X./bin/aegis -diff -nl -lib $worklib -p foo
  5538. Xif test $? -ne 0 ; then fail; fi
  5539. X./bin/aegis -test -nl -lib $worklib -p foo
  5540. Xif test $? -ne 0 ; then fail; fi
  5541. X./bin/aegis -test -bl -nl -lib $worklib -p foo
  5542. Xif test $? -ne 0 ; then fail; fi
  5543. Xif test ! -r $workchan/main.c,D ; then fail ; fi
  5544. X
  5545. X
  5546. X#
  5547. X# end development
  5548. X# review pass
  5549. X# start integrating
  5550. X#
  5551. X./bin/aegis -devend -lib $worklib -p foo
  5552. Xif test $? -ne 0 ; then fail; fi
  5553. X./bin/aegis -revpass -c 2 -p foo -lib $worklib
  5554. Xif test $? -ne 0 ; then fail; fi
  5555. X./bin/aegis -intbeg -c 2 -p foo -lib $worklib
  5556. Xif test $? -ne 0 ; then fail; fi
  5557. X
  5558. X#
  5559. X# build the integration
  5560. X# test the integration
  5561. X# test the integration against the baseline
  5562. X#
  5563. Xsleep 1
  5564. X./bin/aegis -b -nl -lib $worklib -p foo
  5565. Xif test $? -ne 0 ; then fail; fi
  5566. X./bin/aegis -t -nl -lib $worklib -p foo
  5567. Xif test $? -ne 0 ; then fail; fi
  5568. X./bin/aegis -t -bl -nl -lib $worklib -p foo
  5569. Xif test $? -ne 0 ; then fail; fi
  5570. X
  5571. X#
  5572. X# pass the integration
  5573. X#    make sure it create the files, etc
  5574. X#
  5575. X./bin/aegis -intpass -nl -lib $worklib -p foo
  5576. Xif test $? -ne 0 ; then fail; fi
  5577. Xif test ! -r $workproj/info/change/0/002 ; then fail ; fi
  5578. Xif test ! -r $workproj/info/state ; then fail ; fi
  5579. Xif test ! -r $worklib/user/$USER ; then fail ; fi
  5580. X./bin/aegis -l projhist -p foo -lib $worklib
  5581. Xif test $? -ne 0 ; then fail; fi
  5582. X
  5583. X# should be no automatic logging
  5584. Xif test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
  5585. X
  5586. X#
  5587. X# the things tested in this test, worked
  5588. X#
  5589. Xpass
  5590. END_OF_FILE
  5591. if test 14483 -ne `wc -c <'test/00/t0002a.sh'`; then
  5592.     echo shar: \"'test/00/t0002a.sh'\" unpacked with wrong size!
  5593. fi
  5594. # end of 'test/00/t0002a.sh'
  5595. fi
  5596. echo shar: End of archive 10 \(of 19\).
  5597. cp /dev/null ark10isdone
  5598. MISSING=""
  5599. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  5600.     if test ! -f ark${I}isdone ; then
  5601.     MISSING="${MISSING} ${I}"
  5602.     fi
  5603. done
  5604. if test "${MISSING}" = "" ; then
  5605.     echo You have unpacked all 19 archives.
  5606.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  5607. else
  5608.     echo You still need to unpack the following archives:
  5609.     echo "        " ${MISSING}
  5610. fi
  5611. ##  End of shell archive.
  5612. exit 0
  5613.