main.c (eea99451) main.c (9fe7c2c3)
1/*
2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the CVS source distribution.
7 *
8 * This is the main C driver for the CVS system.
9 *
10 * Credit to Dick Grune, Vrije Universiteit, Amsterdam, for writing
11 * the shell-script CVS system that this is based on.
12 *
13 */
14
1/*
2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the CVS source distribution.
7 *
8 * This is the main C driver for the CVS system.
9 *
10 * Credit to Dick Grune, Vrije Universiteit, Amsterdam, for writing
11 * the shell-script CVS system that this is based on.
12 *
13 */
14
15#include <assert.h>
15#include "cvs.h"
16
17#ifdef HAVE_WINSOCK_H
18#include <winsock.h>
19#else
20extern int gethostname ();
21#endif
22

--- 31 unchanged lines hidden (view full) ---

54char *CurDir;
55
56/*
57 * Defaults, for the environment variables that are not set
58 */
59char *Tmpdir = TMPDIR_DFLT;
60char *Editor = EDITOR_DFLT;
61
16#include "cvs.h"
17
18#ifdef HAVE_WINSOCK_H
19#include <winsock.h>
20#else
21extern int gethostname ();
22#endif
23

--- 31 unchanged lines hidden (view full) ---

55char *CurDir;
56
57/*
58 * Defaults, for the environment variables that are not set
59 */
60char *Tmpdir = TMPDIR_DFLT;
61char *Editor = EDITOR_DFLT;
62
63
64/* When our working directory contains subdirectories with different
65 values in CVS/Root files, we maintain a list of them. */
66List *root_directories = NULL;
67
68/* We step through the above values. This variable is set to reflect
69 the currently active value. */
70char *current_root = NULL;
71
72
62static const struct cmd
63{
64 char *fullname; /* Full name of the function (e.g. "commit") */
65
66 /* Synonyms for the command, nick1 and nick2. We supply them
67 mostly for two reasons: (1) CVS has always supported them, and
68 we need to maintain compatibility, (2) if there is a need for a
69 version which is shorter than the fullname, for ease in typing.

--- 163 unchanged lines hidden (view full) ---

233#endif
234 " -a Authenticate all net traffic.\n",
235#endif
236 " -s VAR=VAL Set CVS user variable.\n",
237 "(Specify the --help option for a list of other help options)\n",
238 NULL
239};
240
73static const struct cmd
74{
75 char *fullname; /* Full name of the function (e.g. "commit") */
76
77 /* Synonyms for the command, nick1 and nick2. We supply them
78 mostly for two reasons: (1) CVS has always supported them, and
79 we need to maintain compatibility, (2) if there is a need for a
80 version which is shorter than the fullname, for ease in typing.

--- 163 unchanged lines hidden (view full) ---

244#endif
245 " -a Authenticate all net traffic.\n",
246#endif
247 " -s VAR=VAL Set CVS user variable.\n",
248 "(Specify the --help option for a list of other help options)\n",
249 NULL
250};
251
252
253static int
254set_root_directory (p, ignored)
255 Node *p;
256 void *ignored;
257{
258 if (current_root == NULL && p->data == NULL)
259 {
260 current_root = p->key;
261 return 1;
262 }
263 return 0;
264}
265
266
241static const char * const*
242cmd_synonyms ()
243{
244 char ** synonyms;
245 char ** line;
246 const struct cmd *c = &cmds[0];
247 /* Three more for title, "specify --help" line, and NULL. */
248 int numcmds = 3;

--- 59 unchanged lines hidden (view full) ---

308 /* The following commands do not modify the repository; we
309 conservatively assume that everything else does. Feel free to
310 add to this list if you are _certain_ something is safe. */
311 if ((strcmp (cmd_name, "annotate") != 0) &&
312 (strcmp (cmd_name, "checkout") != 0) &&
313 (strcmp (cmd_name, "diff") != 0) &&
314 (strcmp (cmd_name, "rdiff") != 0) &&
315 (strcmp (cmd_name, "update") != 0) &&
267static const char * const*
268cmd_synonyms ()
269{
270 char ** synonyms;
271 char ** line;
272 const struct cmd *c = &cmds[0];
273 /* Three more for title, "specify --help" line, and NULL. */
274 int numcmds = 3;

--- 59 unchanged lines hidden (view full) ---

334 /* The following commands do not modify the repository; we
335 conservatively assume that everything else does. Feel free to
336 add to this list if you are _certain_ something is safe. */
337 if ((strcmp (cmd_name, "annotate") != 0) &&
338 (strcmp (cmd_name, "checkout") != 0) &&
339 (strcmp (cmd_name, "diff") != 0) &&
340 (strcmp (cmd_name, "rdiff") != 0) &&
341 (strcmp (cmd_name, "update") != 0) &&
316 (strcmp (cmd_name, "history") != 0) &&
317 (strcmp (cmd_name, "editors") != 0) &&
318 (strcmp (cmd_name, "export") != 0) &&
319 (strcmp (cmd_name, "history") != 0) &&
320 (strcmp (cmd_name, "log") != 0) &&
321 (strcmp (cmd_name, "noop") != 0) &&
322 (strcmp (cmd_name, "watchers") != 0) &&
323 (strcmp (cmd_name, "status") != 0))
324 {

--- 78 unchanged lines hidden (view full) ---

403 {"help-synonyms", 0, NULL, 2},
404 {"help-options", 0, NULL, 4},
405 {"allow-root", required_argument, NULL, 3},
406 {0, 0, 0, 0}
407 };
408 /* `getopt_long' stores the option index here, but right now we
409 don't use it. */
410 int option_index = 0;
342 (strcmp (cmd_name, "editors") != 0) &&
343 (strcmp (cmd_name, "export") != 0) &&
344 (strcmp (cmd_name, "history") != 0) &&
345 (strcmp (cmd_name, "log") != 0) &&
346 (strcmp (cmd_name, "noop") != 0) &&
347 (strcmp (cmd_name, "watchers") != 0) &&
348 (strcmp (cmd_name, "status") != 0))
349 {

--- 78 unchanged lines hidden (view full) ---

428 {"help-synonyms", 0, NULL, 2},
429 {"help-options", 0, NULL, 4},
430 {"allow-root", required_argument, NULL, 3},
431 {0, 0, 0, 0}
432 };
433 /* `getopt_long' stores the option index here, but right now we
434 don't use it. */
435 int option_index = 0;
411 int need_to_create_root = 0;
412
413#ifdef SYSTEM_INITIALIZE
414 /* Hook for OS-specific behavior, for example socket subsystems on
415 NT and OS2 or dealing with windows and arguments on Mac. */
416 SYSTEM_INITIALIZE (&argc, &argv);
417#endif
418
419#ifdef HAVE_TZSET

--- 143 unchanged lines hidden (view full) ---

563 free_Tmpdir = 1;
564 tmpdir_update_env = 1; /* need to update environment */
565 break;
566 case 'e':
567 Editor = xstrdup (optarg);
568 free_Editor = 1;
569 break;
570 case 'd':
436
437#ifdef SYSTEM_INITIALIZE
438 /* Hook for OS-specific behavior, for example socket subsystems on
439 NT and OS2 or dealing with windows and arguments on Mac. */
440 SYSTEM_INITIALIZE (&argc, &argv);
441#endif
442
443#ifdef HAVE_TZSET

--- 143 unchanged lines hidden (view full) ---

587 free_Tmpdir = 1;
588 tmpdir_update_env = 1; /* need to update environment */
589 break;
590 case 'e':
591 Editor = xstrdup (optarg);
592 free_Editor = 1;
593 break;
594 case 'd':
595 if (CVSroot_cmdline != NULL)
596 free (CVSroot_cmdline);
597 CVSroot_cmdline = xstrdup (optarg);
571 CVSroot = xstrdup (optarg);
572 free_CVSroot = 1;
573 cvs_update_env = 1; /* need to update environment */
574 break;
575 case 'H':
576 help = 1;
577 break;
578 case 'f':

--- 66 unchanged lines hidden (view full) ---

645 with GNU emacs 19.34 invokes 'cvs rlog' instead of 'cvs log'. */
646 if (strcmp (argv[0], "rlog") == 0)
647 {
648 error (0, 0, "warning: the rlog command is deprecated");
649 error (0, 0, "use the synonymous log command instead");
650 }
651
652 if (help)
598 CVSroot = xstrdup (optarg);
599 free_CVSroot = 1;
600 cvs_update_env = 1; /* need to update environment */
601 break;
602 case 'H':
603 help = 1;
604 break;
605 case 'f':

--- 66 unchanged lines hidden (view full) ---

672 with GNU emacs 19.34 invokes 'cvs rlog' instead of 'cvs log'. */
673 if (strcmp (argv[0], "rlog") == 0)
674 {
675 error (0, 0, "warning: the rlog command is deprecated");
676 error (0, 0, "use the synonymous log command instead");
677 }
678
679 if (help)
680 {
653 argc = -1; /* some functions only check for this */
681 argc = -1; /* some functions only check for this */
682 err = (*(cm->func)) (argc, argv);
683 }
654 else
655 {
656 /* The user didn't ask for help, so go ahead and authenticate,
657 set up CVSROOT, and the rest of it. */
658
659 /* The UMASK environment variable isn't handled with the
660 others above, since we don't want to signal errors if the
661 user has asked for help. This won't work if somebody adds

--- 40 unchanged lines hidden (view full) ---

702
703 /* Pretend we were invoked as a plain server. */
704 command_name = "server";
705 }
706#endif /* (AUTH_SERVER_SUPPORT || HAVE_GSSAPI) && SERVER_SUPPORT */
707
708#ifdef SERVER_SUPPORT
709 server_active = strcmp (command_name, "server") == 0;
684 else
685 {
686 /* The user didn't ask for help, so go ahead and authenticate,
687 set up CVSROOT, and the rest of it. */
688
689 /* The UMASK environment variable isn't handled with the
690 others above, since we don't want to signal errors if the
691 user has asked for help. This won't work if somebody adds

--- 40 unchanged lines hidden (view full) ---

732
733 /* Pretend we were invoked as a plain server. */
734 command_name = "server";
735 }
736#endif /* (AUTH_SERVER_SUPPORT || HAVE_GSSAPI) && SERVER_SUPPORT */
737
738#ifdef SERVER_SUPPORT
739 server_active = strcmp (command_name, "server") == 0;
740#endif
710
741
742 /* This is only used for writing into the history file. For
743 remote connections, it might be nice to have hostname
744 and/or remote path, on the other hand I'm not sure whether
745 it is worth the trouble. */
746
747#ifdef SERVER_SUPPORT
748 if (server_active)
749 CurDir = xstrdup ("<remote>");
750 else
751#endif
752 {
753 CurDir = xgetwd ();
754 if (CurDir == NULL)
755 error (1, errno, "cannot get working directory");
756 }
757
758 if (Tmpdir == NULL || Tmpdir[0] == '\0')
759 Tmpdir = "/tmp";
760
761#ifdef HAVE_PUTENV
762 if (tmpdir_update_env)
763 {
764 char *env;
765 env = xmalloc (strlen (TMPDIR_ENV) + strlen (Tmpdir) + 1 + 1);
766 (void) sprintf (env, "%s=%s", TMPDIR_ENV, Tmpdir);
767 (void) putenv (env);
768 /* do not free env, as putenv has control of it */
769 }
770#endif
771
772#ifndef DONT_USE_SIGNALS
773 /* make sure we clean up on error */
774#ifdef SIGHUP
775 (void) SIG_register (SIGHUP, main_cleanup);
776 (void) SIG_register (SIGHUP, Lock_Cleanup);
777#endif
778#ifdef SIGINT
779 (void) SIG_register (SIGINT, main_cleanup);
780 (void) SIG_register (SIGINT, Lock_Cleanup);
781#endif
782#ifdef SIGQUIT
783 (void) SIG_register (SIGQUIT, main_cleanup);
784 (void) SIG_register (SIGQUIT, Lock_Cleanup);
785#endif
786#ifdef SIGPIPE
787 (void) SIG_register (SIGPIPE, main_cleanup);
788 (void) SIG_register (SIGPIPE, Lock_Cleanup);
789#endif
790#ifdef SIGTERM
791 (void) SIG_register (SIGTERM, main_cleanup);
792 (void) SIG_register (SIGTERM, Lock_Cleanup);
793#endif
794#endif /* !DONT_USE_SIGNALS */
795
796 gethostname(hostname, sizeof (hostname));
797
798#ifdef KLUDGE_FOR_WNT_TESTSUITE
799 /* Probably the need for this will go away at some point once
800 we call fflush enough places (e.g. fflush (stdout) in
801 cvs_outerr). */
802 (void) setvbuf (stdout, (char *) NULL, _IONBF, 0);
803 (void) setvbuf (stderr, (char *) NULL, _IONBF, 0);
804#endif /* KLUDGE_FOR_WNT_TESTSUITE */
805
806 if (use_cvsrc)
807 read_cvsrc (&argc, &argv, command_name);
808
809#ifdef SERVER_SUPPORT
711 /* Fiddling with CVSROOT doesn't make sense if we're running
810 /* Fiddling with CVSROOT doesn't make sense if we're running
712 in server mode, since the client will send the repository
713 directory after the connection is made. */
811 in server mode, since the client will send the repository
812 directory after the connection is made. */
714
715 if (!server_active)
716#endif
717 {
718 char *CVSADM_Root;
719
720 /* See if we are able to find a 'better' value for CVSroot
721 in the CVSADM_ROOT directory. */
722
723 CVSADM_Root = NULL;
724
725 /* "cvs import" shouldn't check CVS/Root; in general it
726 ignores CVS directories and CVS/Root is likely to
727 specify a different repository than the one we are
728 importing to. */
729
813
814 if (!server_active)
815#endif
816 {
817 char *CVSADM_Root;
818
819 /* See if we are able to find a 'better' value for CVSroot
820 in the CVSADM_ROOT directory. */
821
822 CVSADM_Root = NULL;
823
824 /* "cvs import" shouldn't check CVS/Root; in general it
825 ignores CVS directories and CVS/Root is likely to
826 specify a different repository than the one we are
827 importing to. */
828
730 if (lookup_command_attribute (command_name)
731 & CVS_CMD_IGNORE_ADMROOT)
732 {
829 if ((lookup_command_attribute (command_name)
830 & CVS_CMD_IGNORE_ADMROOT)
831
832 /* -d overrides CVS/Root, so don't give an error if the
833 latter points to a nonexistent repository. */
834 && CVSroot_cmdline == NULL)
835 {
733 CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
836 CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
734 }
837 }
735
736 if (CVSADM_Root != NULL)
737 {
738 if (CVSroot == NULL || !cvs_update_env)
739 {
740 CVSroot = CVSADM_Root;
741 cvs_update_env = 1; /* need to update environment */
742 }
838
839 if (CVSADM_Root != NULL)
840 {
841 if (CVSroot == NULL || !cvs_update_env)
842 {
843 CVSroot = CVSADM_Root;
844 cvs_update_env = 1; /* need to update environment */
845 }
743 /* Let -d override CVS/Root file. The user might want
744 to change the access method, use a different server
745 (if there are two server machines which share the
746 repository using a networked file system), etc. */
747 else if (
748#ifdef CLIENT_SUPPORT
749 !getenv ("CVS_IGNORE_REMOTE_ROOT") &&
750#endif
751 strcmp (CVSroot, CVSADM_Root) != 0)
752 {
753 /* Once we have verified that this root is usable,
754 we will want to write it into CVS/Root.
755
756 Don't do it for the "login" command, however.
757 Consider: if the user executes "cvs login" with
758 the working directory inside an already checked
759 out module, we'd incorrectly change the
760 CVS/Root file to reflect the CVSROOT of the
761 "cvs login" command. Ahh, the things one
762 discovers. */
763
764 if (lookup_command_attribute (command_name)
765 & CVS_CMD_USES_WORK_DIR)
766 {
767 need_to_create_root = 1;
768 }
769
770 }
771 }
772
773 /* Now we've reconciled CVSROOT from the command line, the
846 }
847
848 /* Now we've reconciled CVSROOT from the command line, the
774 CVS/Root file, and the environment variable. Do the
775 last sanity checks on the variable. */
849 CVS/Root file, and the environment variable. Do the
850 last sanity checks on the variable. */
776
777 if (! CVSroot)
778 {
779 error (0, 0,
780 "No CVSROOT specified! Please use the `-d' option");
781 error (1, 0,
782 "or set the %s environment variable.", CVSROOT_ENV);
783 }

--- 5 unchanged lines hidden (view full) ---

789 error (0, 0,
790 "specification of CVSROOT is legal, either via the");
791 error (0, 0,
792 "`-d' option, the %s environment variable, or the",
793 CVSROOT_ENV);
794 error (1, 0,
795 "CVS/Root file (if any).");
796 }
851
852 if (! CVSroot)
853 {
854 error (0, 0,
855 "No CVSROOT specified! Please use the `-d' option");
856 error (1, 0,
857 "or set the %s environment variable.", CVSROOT_ENV);
858 }

--- 5 unchanged lines hidden (view full) ---

864 error (0, 0,
865 "specification of CVSROOT is legal, either via the");
866 error (0, 0,
867 "`-d' option, the %s environment variable, or the",
868 CVSROOT_ENV);
869 error (1, 0,
870 "CVS/Root file (if any).");
871 }
872 }
797
873
798 /* Now we're 100% sure that we have a valid CVSROOT
799 variable. Parse it to see if we're supposed to do
800 remote accesses or use a special access method. */
874 /* Here begins the big loop over unique cvsroot values. We
875 need to call do_recursion once for each unique value found
876 in CVS/Root. Prime the list with the current value. */
801
877
802 if (parse_cvsroot (CVSroot))
803 error (1, 0, "Bad CVSROOT.");
878 /* Create the list. */
879 assert (root_directories == NULL);
880 root_directories = getlist ();
804
881
805 /*
806 * Check to see if we can write into the history file. If not,
807 * we assume that we can't work in the repository.
808 * BUT, only if the history file exists.
809 */
882 /* Prime it. */
883 if (CVSroot != NULL)
884 {
885 Node *n;
886 n = getnode ();
887 n->type = UNKNOWN;
888 n->key = xstrdup (CVSroot);
889 n->data = NULL;
810
890
811 if (!client_active)
891 if (addnode (root_directories, n))
892 error (1, 0, "cannot add initial CVSROOT %s", n->key);
893 }
894
895 assert (current_root == NULL);
896
897 /* If we're running the server, we want to execute this main
898 loop once and only once (we won't be serving multiple roots
899 from this connection, so there's no need to do it more than
900 once). To get out of the loop, we perform a "break" at the
901 end of things. */
902
903 while (
904#ifdef SERVER_SUPPORT
905 server_active ||
906#endif
907 walklist (root_directories, set_root_directory, NULL)
908 )
909 {
910#ifdef SERVER_SUPPORT
911 /* Fiddling with CVSROOT doesn't make sense if we're running
912 in server mode, since the client will send the repository
913 directory after the connection is made. */
914
915 if (!server_active)
916#endif
812 {
917 {
813 char *path;
814 int save_errno;
918 /* Now we're 100% sure that we have a valid CVSROOT
919 variable. Parse it to see if we're supposed to do
920 remote accesses or use a special access method. */
815
921
816 path = xmalloc (strlen (CVSroot_directory)
817 + sizeof (CVSROOTADM)
818 + 20
819 + sizeof (CVSROOTADM_HISTORY));
820 (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
821 if (!isaccessible (path, R_OK | X_OK))
922 if (parse_cvsroot (current_root))
923 error (1, 0, "Bad CVSROOT.");
924
925 if (trace)
926 error (0, 0, "notice: main loop with CVSROOT=%s",
927 current_root);
928
929 /*
930 * Check to see if we can write into the history file. If not,
931 * we assume that we can't work in the repository.
932 * BUT, only if the history file exists.
933 */
934
935 if (!client_active)
822 {
936 {
823 save_errno = errno;
824 /* If this is "cvs init", the root need not exist yet. */
825 if (strcmp (command_name, "init") != 0)
937 char *path;
938 int save_errno;
939
940 path = xmalloc (strlen (CVSroot_directory)
941 + sizeof (CVSROOTADM)
942 + 20
943 + sizeof (CVSROOTADM_HISTORY));
944 (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
945 if (!isaccessible (path, R_OK | X_OK))
826 {
946 {
947 save_errno = errno;
948 /* If this is "cvs init", the root need not exist yet. */
949 if (strcmp (command_name, "init") != 0)
950 {
951 error (1, save_errno, "%s", path);
952 }
953 }
954 (void) strcat (path, "/");
955 (void) strcat (path, CVSROOTADM_HISTORY);
956 if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK))
957 {
958 save_errno = errno;
959 error (0, 0, "Sorry, you don't have read/write access to the history file");
827 error (1, save_errno, "%s", path);
828 }
960 error (1, save_errno, "%s", path);
961 }
962 free (path);
829 }
963 }
830 (void) strcat (path, "/");
831 (void) strcat (path, CVSROOTADM_HISTORY);
832 if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK))
833 {
834 save_errno = errno;
835 error (0, 0, "Sorry, you don't have read/write access to the history file");
836 error (1, save_errno, "%s", path);
837 }
838 free (path);
839 }
840
841#ifdef HAVE_PUTENV
964
965#ifdef HAVE_PUTENV
842 /* Update the CVSROOT environment variable if necessary. */
843
844 if (cvs_update_env)
845 {
846 char *env;
847 env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
848 + 1 + 1);
849 (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
850 (void) putenv (env);
851 /* do not free env, as putenv has control of it */
852 }
966 /* Update the CVSROOT environment variable if necessary. */
967 /* FIXME (njc): should we always set this with the CVSROOT from the command line? */
968 if (cvs_update_env)
969 {
970 char *env;
971 env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
972 + 1 + 1);
973 (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
974 (void) putenv (env);
975 /* do not free env, as putenv has control of it */
976 }
853#endif
977#endif
854 }
978 }
855
979
856 /* This is only used for writing into the history file. For
857 remote connections, it might be nice to have hostname
858 and/or remote path, on the other hand I'm not sure whether
859 it is worth the trouble. */
860
980 /* Parse the CVSROOT/config file, but only for local. For the
981 server, we parse it after we know $CVSROOT. For the
982 client, it doesn't get parsed at all, obviously. The
983 presence of the parse_config call here is not mean to
984 predetermine whether CVSROOT/config overrides things from
985 read_cvsrc and other such places or vice versa. That sort
986 of thing probably needs more thought. */
987 if (1
861#ifdef SERVER_SUPPORT
988#ifdef SERVER_SUPPORT
862 if (server_active)
863 CurDir = xstrdup ("<remote>");
864 else
989 && !server_active
865#endif
990#endif
866 {
867 CurDir = xgetwd ();
868 if (CurDir == NULL)
869 error (1, errno, "cannot get working directory");
870 }
871
872 if (Tmpdir == NULL || Tmpdir[0] == '\0')
873 Tmpdir = "/tmp";
874
875#ifdef HAVE_PUTENV
876 if (tmpdir_update_env)
877 {
878 char *env;
879 env = xmalloc (strlen (TMPDIR_ENV) + strlen (Tmpdir) + 1 + 1);
880 (void) sprintf (env, "%s=%s", TMPDIR_ENV, Tmpdir);
881 (void) putenv (env);
882 /* do not free env, as putenv has control of it */
883 }
991#ifdef CLIENT_SUPPORT
992 && !client_active
884#endif
993#endif
994 )
995 {
996 /* If there was an error parsing the config file, parse_config
997 already printed an error. We keep going. Why? Because
998 if we didn't, then there would be no way to check in a new
999 CVSROOT/config file to fix the broken one! */
1000 parse_config (CVSroot_directory);
1001 }
885
1002
886#ifndef DONT_USE_SIGNALS
887 /* make sure we clean up on error */
888#ifdef SIGHUP
889 (void) SIG_register (SIGHUP, main_cleanup);
890 (void) SIG_register (SIGHUP, Lock_Cleanup);
1003#ifdef CLIENT_SUPPORT
1004 if (client_active)
1005 {
1006 /* Create a new list for directory names that we've
1007 sent to the server. */
1008 if (dirs_sent_to_server != NULL)
1009 dellist (&dirs_sent_to_server);
1010 dirs_sent_to_server = getlist ();
1011 }
891#endif
1012#endif
892#ifdef SIGINT
893 (void) SIG_register (SIGINT, main_cleanup);
894 (void) SIG_register (SIGINT, Lock_Cleanup);
895#endif
896#ifdef SIGQUIT
897 (void) SIG_register (SIGQUIT, main_cleanup);
898 (void) SIG_register (SIGQUIT, Lock_Cleanup);
899#endif
900#ifdef SIGPIPE
901 (void) SIG_register (SIGPIPE, main_cleanup);
902 (void) SIG_register (SIGPIPE, Lock_Cleanup);
903#endif
904#ifdef SIGTERM
905 (void) SIG_register (SIGTERM, main_cleanup);
906 (void) SIG_register (SIGTERM, Lock_Cleanup);
907#endif
908#endif /* !DONT_USE_SIGNALS */
909
1013
910 gethostname(hostname, sizeof (hostname));
1014 err = (*(cm->func)) (argc, argv);
1015
1016 /* Mark this root directory as done. When the server is
1017 active, current_root will be NULL -- don't try and
1018 remove it from the list. */
911
1019
912#ifdef KLUDGE_FOR_WNT_TESTSUITE
913 /* Probably the need for this will go away at some point once
914 we call fflush enough places (e.g. fflush (stdout) in
915 cvs_outerr). */
916 (void) setvbuf (stdout, (char *) NULL, _IONBF, 0);
917 (void) setvbuf (stderr, (char *) NULL, _IONBF, 0);
918#endif /* KLUDGE_FOR_WNT_TESTSUITE */
1020 if (current_root != NULL)
1021 {
1022 Node *n = findnode (root_directories, current_root);
1023 assert (n != NULL);
1024 n->data = (void *) 1;
1025 current_root = NULL;
1026 }
1027
1028#if 0
1029 /* This will not work yet, since it tries to free (void *) 1. */
1030 dellist (&root_directories);
1031#endif
919
1032
920 if (use_cvsrc)
921 read_cvsrc (&argc, &argv, command_name);
922
923 /* Parse the CVSROOT/config file, but only for local. For the
924 server, we parse it after we know $CVSROOT. For the
925 client, it doesn't get parsed at all, obviously. The
926 presence of the parse_config call here is not mean to
927 predetermine whether CVSROOT/config overrides things from
928 read_cvsrc and other such places or vice versa. That sort
929 of thing probably needs more thought. */
930 if (1
931#ifdef SERVER_SUPPORT
1033#ifdef SERVER_SUPPORT
932 && !server_active
1034 if (server_active)
1035 break;
933#endif
1036#endif
934#ifdef CLIENT_SUPPORT
935 && !client_active
936#endif
937 )
938 {
939 /* If there was an error parsing the config file, parse_config
940 already printed an error. We keep going. Why? Because
941 if we didn't, then there would be no way to check in a new
942 CVSROOT/config file to fix the broken one! */
943 parse_config (CVSroot_directory);
944 }
1037 } /* end of loop for cvsroot values */
1038
945 } /* end of stuff that gets done if the user DOESN'T ask for help */
946
1039 } /* end of stuff that gets done if the user DOESN'T ask for help */
1040
947 err = (*(cm->func)) (argc, argv);
948
949 if (need_to_create_root)
950 {
951 /* Update the CVS/Root file. We might want to do this in
952 all directories that we recurse into, but currently we
953 don't. Note that if there is an error writing the file,
954 we give an error/warning. This is so if users try to rewrite
955 CVS/Root with the -d option (a documented feature), they will
956 either succeed, or be told why it didn't work. */
957 Create_Root (NULL, CVSroot);
958 }
959
960 Lock_Cleanup ();
961
962 free (program_path);
1041 Lock_Cleanup ();
1042
1043 free (program_path);
1044 if (CVSroot_cmdline != NULL)
1045 free (CVSroot_cmdline);
963 if (free_CVSroot)
964 free (CVSroot);
965 if (free_Editor)
966 free (Editor);
967 if (free_Tmpdir)
968 free (Tmpdir);
969 root_allow_free ();
970

--- 50 unchanged lines hidden (view full) ---

1021 (void) sprintf (date, DATEFORM,
1022 ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
1023 ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
1024 ftm->tm_min, ftm->tm_sec);
1025 ret = xstrdup (date);
1026 return (ret);
1027}
1028
1046 if (free_CVSroot)
1047 free (CVSroot);
1048 if (free_Editor)
1049 free (Editor);
1050 if (free_Tmpdir)
1051 free (Tmpdir);
1052 root_allow_free ();
1053

--- 50 unchanged lines hidden (view full) ---

1104 (void) sprintf (date, DATEFORM,
1105 ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
1106 ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
1107 ftm->tm_min, ftm->tm_sec);
1108 ret = xstrdup (date);
1109 return (ret);
1110}
1111
1112/* Convert a date to RFC822/1123 format. This is used in contexts like
1113 dates to send in the protocol; it should not vary based on locale or
1114 other such conventions for users. We should have another routine which
1115 does that kind of thing.
1116
1117 The SOURCE date is in our internal RCS format. DEST should point to
1118 storage managed by the caller, at least MAXDATELEN characters. */
1029void
1119void
1120date_to_internet (dest, source)
1121 char *dest;
1122 char *source;
1123{
1124 int year, month, day, hour, minute, second;
1125
1126 /* Just to reiterate, these strings are from RFC822 and do not vary
1127 according to locale. */
1128 static const char *const month_names[] =
1129 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
1130 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
1131
1132 if (sscanf (source, SDATEFORM,
1133 &year, &month, &day, &hour, &minute, &second)
1134 != 6)
1135 /* Is there a better way to handle errors here? I made this
1136 non-fatal in case we are called from the code which can't
1137 deal with fatal errors. */
1138 error (0, 0, "internal error: bad date %s", source);
1139
1140 /* Always send a four digit year. */
1141 if (year < 100)
1142 year += 1900;
1143
1144 sprintf (dest, "%d %s %d %02d:%02d:%02d -0000", day,
1145 month < 1 || month > 12 ? "???" : month_names[month - 1],
1146 year, hour, minute, second);
1147}
1148
1149void
1030usage (cpp)
1031 register const char *const *cpp;
1032{
1033 (void) fprintf (stderr, *cpp++, program_name, command_name);
1034 for (; *cpp; cpp++)
1035 (void) fprintf (stderr, *cpp);
1036 error_exit();
1037}
1150usage (cpp)
1151 register const char *const *cpp;
1152{
1153 (void) fprintf (stderr, *cpp++, program_name, command_name);
1154 for (; *cpp; cpp++)
1155 (void) fprintf (stderr, *cpp);
1156 error_exit();
1157}