6051 lines
170 KiB
C
6051 lines
170 KiB
C
/*
|
|
* COMPONENT_NAME: BLDPROCESS
|
|
*
|
|
* FUNCTIONS: ATOI
|
|
* alloc_comment_leader5192
|
|
* bcreate_undo
|
|
* check_path
|
|
* confirm_alloc
|
|
* copy_file
|
|
* defined
|
|
* full_set_name
|
|
* get_bmerge_action1877
|
|
* get_full_setname2332
|
|
* get_src_and_org_paths
|
|
* get_str
|
|
* getenv_user
|
|
* is_in_error
|
|
* log_error
|
|
* makedir
|
|
* match_comment_leader5253
|
|
* merge_elem
|
|
* new_set_cleanup
|
|
* new_set_insert
|
|
* real_check_in_file3530
|
|
* remove_working_file1230
|
|
* sci_add_to_list
|
|
* sci_add_to_list_as_is2657
|
|
* sci_all_list
|
|
* sci_ancestor_list3210
|
|
* sci_ancestor_update_list1082
|
|
* sci_ancestor_update_list21117
|
|
* sci_check_in_elem3309
|
|
* sci_check_in_file3594
|
|
* sci_check_in_list3441
|
|
* sci_check_in_list23482
|
|
* sci_config_lookup_list4206
|
|
* sci_create_files4643
|
|
* sci_delete_files4830
|
|
* sci_diff_rev_with_file4300
|
|
* sci_diff_rev_with_rev4368
|
|
* sci_edit_files
|
|
* sci_elem_cnt
|
|
* sci_first
|
|
* sci_get_comment_leader1385
|
|
* sci_has_log
|
|
* sci_init
|
|
* sci_init2
|
|
* sci_init3
|
|
* sci_is_branch
|
|
* sci_lock_list
|
|
* sci_lookup_ancestor_rev_list3040
|
|
* sci_lookup_latest_rev_list2993
|
|
* sci_lookup_leader_list2806
|
|
* sci_lookup_merge_rev_list3148
|
|
* sci_lookup_rev_list3088
|
|
* sci_lookup_user_rev_list2924
|
|
* sci_merge_list
|
|
* sci_new_list
|
|
* sci_next
|
|
* sci_outdate_list4043
|
|
* sci_outdate_list_p14113
|
|
* sci_outdate_list_p24154
|
|
* sci_read_file
|
|
* sci_read_files
|
|
* sci_real_fast_lookup_latest_rev_list5811
|
|
* sci_real_fast_lookup_user_rev_list5653
|
|
* sci_rm_submit
|
|
* sci_select_not_exists4999
|
|
* sci_set_cmt_leader_list2834
|
|
* sci_set_comment_leader5158
|
|
* sci_set_symbol_list4411
|
|
* sci_show_log_list4230
|
|
* sci_submit
|
|
* sci_trackfile
|
|
* sci_update_build_file3979
|
|
* sci_update_build_list4012
|
|
* set_and_log_kludge2867
|
|
* set_cleanup
|
|
* set_create
|
|
* set_delete
|
|
* set_exists
|
|
* set_file_pathname5312
|
|
* set_fopen
|
|
* set_fread
|
|
* set_insert
|
|
* set_log_pathname5322
|
|
* set_lookup
|
|
* set_path_pathname5332
|
|
* set_remove
|
|
* set_source_info
|
|
* setup_bcstemp
|
|
* simple_cmp_func
|
|
* src_ctl_config_lookup1521
|
|
* src_ctl_merge
|
|
* src_ctl_prep_merge1464
|
|
* src_ctl_set_remove2120
|
|
* src_ctl_setup_merge1450
|
|
* tail_pathname
|
|
* temp_func
|
|
* tmpfile_base
|
|
* tmpfile_create
|
|
* tmpfile_delete
|
|
* tmpfile_name
|
|
* track_insert
|
|
* trunk_revision
|
|
*
|
|
* ORIGINS: 27,71
|
|
*
|
|
* This module contains IBM CONFIDENTIAL code. -- (IBM
|
|
* Confidential Restricted when combined with the aggregated
|
|
* modules for this product)
|
|
* OBJECT CODE ONLY SOURCE MATERIALS
|
|
*
|
|
* (C) COPYRIGHT International Business Machines Corp. 1994
|
|
* All Rights Reserved
|
|
* US Government Users Restricted Rights - Use, duplication or
|
|
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
*/
|
|
/*
|
|
* COPYRIGHT NOTICE
|
|
* Copyright (c) 1992, 1991, 1990
|
|
* Open Software Foundation, Inc.
|
|
*
|
|
* Permission is hereby granted to use, copy, modify and freely distribute
|
|
* the software in this file and its documentation for any purpose without
|
|
* fee, provided that the above copyright notice appears in all copies and
|
|
* that both the copyright notice and this permission notice appear in
|
|
* supporting documentation. Further, provided that the name of Open
|
|
* Software Foundation, Inc. ("OSF") not be used in advertising or
|
|
* publicity pertaining to distribution of the software without prior
|
|
* written permission from OSF. OSF makes no representations about the
|
|
* suitability of this software for any purpose. It is provided "as is"
|
|
* without express or implied warranty.
|
|
*
|
|
* Copyright (c) 1992 Carnegie Mellon University
|
|
* All Rights Reserved.
|
|
*
|
|
* Permission to use, copy, modify and distribute this software and its
|
|
* documentation is hereby granted, provided that both the copyright
|
|
* notice and this permission notice appear in all copies of the
|
|
* software, derivative works or modified versions, and any portions
|
|
* thereof, and that both notices appear in supporting documentation.
|
|
*
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
|
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
|
*
|
|
* Carnegie Mellon requests users of this software to return to
|
|
*
|
|
* Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
|
|
* School of Computer Science
|
|
* Carnegie Mellon University
|
|
* Pittsburgh PA 15213-3890
|
|
*
|
|
* any improvements or extensions that they make and grant Carnegie Mellon
|
|
* the rights to redistribute these changes.
|
|
*/
|
|
/*
|
|
* HISTORY
|
|
* $Log: sci.c,v $
|
|
* Revision 1.5.7.21 1993/12/02 22:01:44 damon
|
|
* CR 882. changed leader to sci_ptr -> leader
|
|
* [1993/12/02 22:01:28 damon]
|
|
*
|
|
* Revision 1.5.7.20 1993/12/02 21:17:18 damon
|
|
* CR 882. Check for NULL before doing strcmp() on leader
|
|
* [1993/12/02 21:15:25 damon]
|
|
*
|
|
* Revision 1.5.7.19 1993/11/12 18:10:24 damon
|
|
* CR 789. sci_create_files() prints files as they are created
|
|
* [1993/11/12 18:10:03 damon]
|
|
*
|
|
* Revision 1.5.7.18 1993/11/10 19:17:09 root
|
|
* CR 463. Pedantic changes
|
|
* [1993/11/10 19:16:24 root]
|
|
*
|
|
* Revision 1.5.7.17 1993/11/05 23:18:45 damon
|
|
* CR 463. Pedantic changes
|
|
* [1993/11/05 23:18:19 damon]
|
|
*
|
|
* Revision 1.5.7.16 1993/11/05 22:43:24 damon
|
|
* CR 463. Pedantic changes
|
|
* [1993/11/05 22:41:29 damon]
|
|
*
|
|
* Revision 1.5.7.15 1993/11/05 20:34:28 damon
|
|
* CR 463. Pedantic changes
|
|
* [1993/11/05 20:33:42 damon]
|
|
*
|
|
* Revision 1.5.7.14 1993/11/03 20:58:18 damon
|
|
* CR 463. More pedantic
|
|
* [1993/11/03 20:57:46 damon]
|
|
*
|
|
* Revision 1.5.7.13 1993/11/03 20:40:56 damon
|
|
* CR 463. More pedantic
|
|
* [1993/11/03 20:38:24 damon]
|
|
*
|
|
* Revision 1.5.7.12 1993/11/03 00:08:32 damon
|
|
* Merged with changes from 1.5.7.11
|
|
* [1993/11/03 00:08:12 damon]
|
|
*
|
|
* CR 739. Complain if revision of file is not present
|
|
* [1993/11/03 00:04:36 damon]
|
|
*
|
|
* Revision 1.5.7.11 1993/11/02 23:24:04 marty
|
|
* CR # 757 - bdiff now prints out an error message if an invalid revision number is specified.
|
|
* [1993/11/02 23:23:40 marty]
|
|
*
|
|
* Revision 1.5.7.10 1993/10/29 12:51:26 damon
|
|
* CR 766. Renamed #odexmXXXXXX to #srvtmpXXXXXX
|
|
* [1993/10/29 12:47:32 damon]
|
|
*
|
|
* Revision 1.5.7.9 1993/10/29 12:26:19 damon
|
|
* CR 698. No files in set was still VFATAL. Changed to VWARN
|
|
* [1993/10/29 12:26:06 damon]
|
|
*
|
|
* Revision 1.5.7.8 1993/10/29 12:21:19 damon
|
|
* CR 751. Give more explicit msg if file writeable at bco
|
|
* [1993/10/29 12:11:07 damon]
|
|
*
|
|
* Revision 1.5.7.7 1993/10/26 22:49:55 damon
|
|
* CR 752. Give more detail
|
|
* [1993/10/26 22:49:37 damon]
|
|
*
|
|
* Revision 1.5.7.6 1993/10/26 21:33:43 damon
|
|
* CR 141. Complain if file is defunct
|
|
* [1993/10/26 21:33:25 damon]
|
|
*
|
|
* Revision 1.5.7.5 1993/10/07 20:18:28 damon
|
|
* CR 733. Properly set expansion mode depending on leader
|
|
* [1993/10/07 20:18:11 damon]
|
|
*
|
|
* Revision 1.5.7.4 1993/10/07 19:53:33 damon
|
|
* CR 722. Complain when comment leader has no space at end
|
|
* [1993/10/07 19:52:43 damon]
|
|
*
|
|
* Revision 1.5.7.3 1993/10/06 23:51:33 damon
|
|
* CR 697
|
|
* Properly handle being in bottom link of backing chain.
|
|
* Complain if trying to submit from same.
|
|
* [1993/10/06 23:51:19 damon]
|
|
*
|
|
* Revision 1.5.7.2 1993/10/06 22:19:23 damon
|
|
* CR 717. Removed references to BCSTEMP env var
|
|
* [1993/10/06 22:17:30 damon]
|
|
*
|
|
* Revision 1.5.7.1 1993/10/06 21:57:16 damon
|
|
* CR 729. Properly initialize tcp_service_number
|
|
* [1993/10/06 21:57:02 damon]
|
|
*
|
|
* Revision 1.5.5.18 1993/10/01 19:05:38 damon
|
|
* CR 698. Made message warning of no files in set more palatable
|
|
* [1993/10/01 19:03:24 damon]
|
|
*
|
|
* Revision 1.5.5.17 1993/09/29 15:54:24 damon
|
|
* CR 707. Handles mixed submission of defunct and regular files
|
|
* [1993/09/29 15:53:31 damon]
|
|
*
|
|
* Revision 1.5.5.16 1993/09/29 14:30:07 root
|
|
* rios porting errors
|
|
* [1993/09/29 14:22:15 root]
|
|
*
|
|
* Revision 1.5.5.15 1993/09/24 18:24:01 damon
|
|
* CR 692. Fixed length mismatch for tmpdir2
|
|
* [1993/09/24 18:21:46 damon]
|
|
*
|
|
* Revision 1.5.5.14 1993/09/24 17:44:01 marty
|
|
* CR # 686 - Fix double # # during bcreate.
|
|
* [1993/09/24 17:43:35 marty]
|
|
*
|
|
* Revision 1.5.5.13 1993/09/24 17:23:20 damon
|
|
* CR 687. Fixed COPYRIGHT NOTICE checking
|
|
* [1993/09/24 17:22:49 damon]
|
|
*
|
|
* Revision 1.5.5.12 1993/09/24 17:14:43 marty
|
|
* CR # 685 - fix sci_create_files() to check for check_copyrights before processing.
|
|
* [1993/09/24 17:14:15 marty]
|
|
*
|
|
* Revision 1.5.5.11 1993/09/23 14:29:19 damon
|
|
* CR 656. Use raw copyrights instead of valid ones
|
|
* [1993/09/23 14:28:21 damon]
|
|
*
|
|
* Revision 1.5.5.10 1993/09/21 21:21:43 marty
|
|
* Cr # 670 - sci_create_files() now supports named copyrights.
|
|
* [1993/09/21 21:21:16 marty]
|
|
*
|
|
* Revision 1.5.5.9 1993/09/16 17:19:16 damon
|
|
* Added COPYRIGHT NOTICE handling
|
|
* [1993/09/16 17:18:03 damon]
|
|
*
|
|
* Revision 1.5.5.8 1993/09/07 16:34:22 damon
|
|
* CR 625. Fixed bsubmit -info
|
|
* [1993/09/07 16:33:30 damon]
|
|
*
|
|
* Revision 1.5.5.7 1993/09/02 20:44:54 damon
|
|
* CR 604. Handle ci return values properly
|
|
* [1993/09/02 20:44:32 damon]
|
|
*
|
|
* Revision 1.5.5.6 1993/09/02 17:22:46 damon
|
|
* CR 648. sci_read_files() now prints each file processed
|
|
* [1993/09/02 17:22:32 damon]
|
|
*
|
|
* Revision 1.5.5.5 1993/09/02 15:55:26 damon
|
|
* CR 631. Enabled abort option in bci
|
|
* [1993/09/02 15:54:53 damon]
|
|
*
|
|
* Revision 1.5.5.4 1993/09/01 19:44:58 marty
|
|
* CR # 646 - Use strdup() on (char *) variables instead of strcpy().
|
|
* [1993/09/01 19:44:37 marty]
|
|
*
|
|
* Revision 1.5.5.3 1993/08/31 21:25:25 damon
|
|
* CR 641. Take care of case where all files are being defuncted
|
|
* [1993/08/31 21:24:56 damon]
|
|
*
|
|
* Revision 1.5.5.2 1993/08/31 18:15:55 damon
|
|
* CR 636. call okmesg more intelligently
|
|
* [1993/08/31 18:14:13 damon]
|
|
*
|
|
* Revision 1.5.5.1 1993/08/30 19:12:07 damon
|
|
* CR 633. Restored writing to file for src_ctl_diff_rev_with_file
|
|
* [1993/08/30 19:11:13 damon]
|
|
*
|
|
* Revision 1.5.3.1 1993/07/09 21:09:33 damon
|
|
* CR 601. -read checks out files read only
|
|
* [1993/07/09 21:09:10 damon]
|
|
*
|
|
* Revision 1.5.1.75 1993/06/30 18:57:40 marty
|
|
* CR # 586 - Print out a little info if revision info gets out of sync.
|
|
* [1993/06/30 18:56:56 marty]
|
|
*
|
|
* Revision 1.5.1.74 1993/06/30 18:47:22 marty
|
|
* CR # 586 - If rcsstat does not return the exact list of files requested
|
|
* (by the *real_fast* revision lookup routines) then return a status
|
|
* ERROR.
|
|
* [1993/06/30 18:46:59 marty]
|
|
*
|
|
* Revision 1.5.1.73 1993/06/18 18:32:01 marty
|
|
* CR # 593 - sci_submit should call enter().
|
|
* [1993/06/18 18:31:38 marty]
|
|
*
|
|
* Revision 1.5.1.72 1993/06/10 21:22:31 damon
|
|
* CR 585. do not skip in sci_real_fast_lookup_user_rev_list()
|
|
* [1993/06/10 21:22:19 damon]
|
|
*
|
|
* Revision 1.5.1.71 1993/06/08 19:28:14 marty
|
|
* CR # 575 - Get rid of all calls to src_ctl_config*() routines.
|
|
* [1993/06/08 19:27:52 marty]
|
|
*
|
|
* Revision 1.5.1.70 1993/06/08 19:21:23 damon
|
|
* CR 579. Use File is defunct message for new branch when defuncting
|
|
* [1993/06/08 19:20:41 damon]
|
|
*
|
|
* Revision 1.5.1.69 1993/06/08 19:00:13 marty
|
|
* Merged with changes from 1.5.1.68
|
|
* [1993/06/08 18:59:55 marty]
|
|
*
|
|
* CR # 476 - bcreate_undo() now makes a separate call to remove empty soruce control files.
|
|
* [1993/06/08 18:56:06 marty]
|
|
*
|
|
* Revision 1.5.1.68 1993/06/08 18:16:01 damon
|
|
* CR 577. Run makedir() before renaming file from temp dir
|
|
* [1993/06/08 18:15:43 damon]
|
|
*
|
|
* Revision 1.5.1.67 1993/06/07 18:10:41 marty
|
|
* CR # 508 - Remove #odexm directory after calling sci_*_real_fast_*() routines.
|
|
* [1993/06/07 18:10:15 marty]
|
|
*
|
|
* Revision 1.5.1.66 1993/06/07 16:14:05 marty
|
|
* CR # 554 - Tools run outside a sandbox in the wrong directory exit gracefully.
|
|
* [1993/06/07 16:13:32 marty]
|
|
*
|
|
* Revision 1.5.1.65 1993/06/04 20:30:42 damon
|
|
* CR 553. Init tcp_service_number to NULL
|
|
* [1993/06/04 20:30:30 damon]
|
|
*
|
|
* Revision 1.5.1.64 1993/06/03 18:21:30 marty
|
|
* CR # 567 - sci_edit_files() checks to see if file exists before stating it.
|
|
* [1993/06/03 18:21:10 marty]
|
|
*
|
|
* Revision 1.5.1.63 1993/06/03 17:23:31 marty
|
|
* CR # 69 - Roll back submission.
|
|
* [1993/06/03 17:22:54 marty]
|
|
*
|
|
* Revision 1.5.1.62 1993/06/03 17:01:28 marty
|
|
* CR # 69 - bdiff now works on symbolic links with the "-r" AND "-R" options.
|
|
* [1993/06/03 17:01:05 marty]
|
|
*
|
|
* Revision 1.5.1.61 1993/06/02 19:58:19 marty
|
|
* CR # 566 - Make src_path global.
|
|
* [1993/06/02 19:58:00 marty]
|
|
*
|
|
* Revision 1.5.1.60 1993/06/02 19:33:48 damon
|
|
* CR 559. alloc_comment_leader now returns NULL if no match
|
|
* [1993/06/02 19:32:46 damon]
|
|
*
|
|
* Revision 1.5.1.59 1993/06/02 18:27:18 damon
|
|
* CR 565. Fixed check for writeable file to deal with links
|
|
* [1993/06/02 18:26:19 damon]
|
|
*
|
|
* Revision 1.5.1.58 1993/06/02 17:50:30 damon
|
|
* CR 563. No longer enter Initial Revision marker during submit of new file
|
|
* [1993/06/02 17:49:57 damon]
|
|
*
|
|
* Revision 1.5.1.57 1993/06/02 13:52:08 damon
|
|
* CR 517. Cleaned up subprojects wrt sb.conf and sc.conf
|
|
* [1993/06/02 13:50:52 damon]
|
|
*
|
|
* Revision 1.5.1.56 1993/05/27 19:49:27 marty
|
|
* CR # 558 - clean up for rios_aix build
|
|
* [1993/05/27 19:49:03 marty]
|
|
*
|
|
* CR # 558 - get it building on rios_aix
|
|
* [1993/05/27 19:16:28 marty]
|
|
*
|
|
* Revision 1.5.1.55 1993/05/27 14:37:53 marty
|
|
* CR # 556 - No longer hangs, and doesn't create *.tmp file with comment leader
|
|
* BIN or NONE.
|
|
* [1993/05/27 14:37:25 marty]
|
|
*
|
|
* Revision 1.5.1.54 1993/05/26 21:02:57 damon
|
|
* CR 545. Use stat() instead of access() for sci_edit_files
|
|
* [1993/05/26 20:46:45 damon]
|
|
*
|
|
* Revision 1.5.1.53 1993/05/26 18:07:56 damon
|
|
* CR 553. Get tcp_service_number from sc.conf
|
|
* [1993/05/26 17:18:43 damon]
|
|
*
|
|
* Revision 1.5.1.52 1993/05/26 01:15:39 damon
|
|
* CR 452. Added -q to co in sci_read_file()
|
|
* [1993/05/26 01:14:58 damon]
|
|
*
|
|
* Revision 1.5.1.51 1993/05/24 19:16:07 marty
|
|
* CR # 535 - Remove links when checking out a file.
|
|
* [1993/05/24 19:15:36 marty]
|
|
*
|
|
* Revision 1.5.1.50 1993/05/20 16:17:20 marty
|
|
* CR # 455 - Print out a better message when detecting bad history section.
|
|
* [1993/05/20 16:15:29 marty]
|
|
*
|
|
* Revision 1.5.1.49 1993/05/17 14:59:16 marty
|
|
* CR # 516 - Fix "fast" routines for looking up revision numbers.
|
|
* [1993/05/17 14:58:56 marty]
|
|
*
|
|
* Revision 1.5.1.48 1993/05/14 21:40:43 damon
|
|
* CR 527. Fixed creation of org_path for null case
|
|
* [1993/05/14 21:40:25 damon]
|
|
*
|
|
* Revision 1.5.1.47 1993/05/14 16:51:34 damon
|
|
* CR 518. Changed prj_read and prj_write to take full sb path
|
|
* [1993/05/14 16:51:18 damon]
|
|
*
|
|
* Revision 1.5.1.46 1993/05/13 16:48:35 marty
|
|
* CR # 516 - sci_real_fast_lookup_user_rev_list() needs to handle defunct files.
|
|
* [1993/05/13 16:48:15 marty]
|
|
*
|
|
* Revision 1.5.1.45 1993/05/13 16:07:33 marty
|
|
* CR # 516 - Fixes to sci_real_fast_lookup_user_rev_list().
|
|
* [1993/05/13 16:07:02 marty]
|
|
*
|
|
* CR # 516 - Debugging sci_real_fast_lookup_user_list().
|
|
* [1993/05/13 15:32:02 marty]
|
|
*
|
|
* Revision 1.5.1.44 1993/05/12 19:55:34 damon
|
|
* CR 517. Merged with martys code
|
|
* [1993/05/12 19:55:13 damon]
|
|
*
|
|
* CR 517. Added subprojects
|
|
* *
|
|
* Revision 1.5.1.43 1993/05/12 19:41:20 marty
|
|
* CR # 480 - More support for "bcs -r"
|
|
* [1993/05/12 16:25:40 marty]
|
|
* *
|
|
* Revision 1.5.1.42 1993/05/11 21:12:01 damon
|
|
* CR 468. Made file locking customizeable
|
|
* [1993/05/11 21:11:01 damon]
|
|
* *
|
|
* Revision 1.5.1.41 1993/05/11 17:10:39 marty
|
|
* CR # 480, add "av[i]=NULL;" to sci_set_comment_leader().
|
|
* [1993/05/11 17:10:19 marty]
|
|
*
|
|
* Revision 1.5.1.40 1993/05/10 19:51:09 damon
|
|
* CR 507. Removed bogus call to track_insert
|
|
* [1993/05/10 19:50:39 damon]
|
|
*
|
|
* Revision 1.5.1.39 1993/05/07 17:46:51 damon
|
|
* CR 498. bci/bco now print file being processed
|
|
* [1993/05/07 17:46:25 damon]
|
|
*
|
|
* Revision 1.5.1.38 1993/05/07 14:43:47 marty
|
|
* Update print statement, needs a carrage return.
|
|
* [1993/05/07 14:43:29 marty]
|
|
*
|
|
* Revision 1.5.1.37 1993/05/07 14:38:04 damon
|
|
* CR 436. dont need to outdate outdated file
|
|
* [1993/05/07 14:37:50 damon]
|
|
*
|
|
* Revision 1.5.1.36 1993/05/06 19:30:32 damon
|
|
* CR 482. Added sci_an*_up*_list2 to convert .BCSconfig to ancestry
|
|
* [1993/05/06 19:30:13 damon]
|
|
*
|
|
* Revision 1.5.1.35 1993/05/06 17:49:48 damon
|
|
* CR 477. Made ancestry buffers dynamic
|
|
* [1993/05/06 17:49:35 damon]
|
|
*
|
|
* Revision 1.5.1.34 1993/05/06 14:46:34 marty
|
|
* Rearrange order of include files for pmax_ultrix.
|
|
* [1993/05/06 14:46:14 marty]
|
|
*
|
|
* Revision 1.5.1.33 1993/05/05 19:16:54 damon
|
|
* CR 479. sci_submit was using /tmp/_LOG_. Now uses opentemp() dir
|
|
* [1993/05/05 19:16:40 damon]
|
|
*
|
|
* Revision 1.5.1.32 1993/05/05 18:42:05 damon
|
|
* CR 489. Added sci_select_not_exists()
|
|
* [1993/05/05 18:41:26 damon]
|
|
*
|
|
* Revision 1.5.1.31 1993/05/05 15:16:08 marty
|
|
* Added include file sys/stat.h for hpux.
|
|
* [1993/05/05 15:15:49 marty]
|
|
*
|
|
* Revision 1.5.1.30 1993/05/05 14:18:14 damon
|
|
* CR 491. Added sci_elem_cnt()
|
|
* [1993/05/05 14:17:52 damon]
|
|
*
|
|
* Revision 1.5.1.29 1993/05/04 21:02:26 damon
|
|
* CR 483. getancestor now returns OE_ANCESTOR when no ancestor
|
|
* [1993/05/04 21:02:08 damon]
|
|
*
|
|
* Revision 1.5.1.28 1993/05/04 18:13:18 marty
|
|
* Removed debugging code.
|
|
* [1993/05/04 18:12:59 marty]
|
|
*
|
|
* Revision 1.5.1.27 1993/05/04 17:47:06 marty
|
|
* Changed call to rcsstat_f to rcsstat.
|
|
* [1993/05/04 17:46:16 marty]
|
|
*
|
|
* Revision 1.5.1.26 1993/04/30 21:58:26 marty
|
|
* Set submitting to FALSE
|
|
* [1993/04/30 21:58:02 marty]
|
|
*
|
|
* Revision 1.5.1.25 1993/04/30 20:41:40 damon
|
|
* CR 467. Check and set r/w permissions for bci/bco correctly
|
|
* [1993/04/30 20:41:19 damon]
|
|
*
|
|
* Revision 1.5.1.24 1993/04/29 20:54:49 marty
|
|
* Added sci_real_fast_*() functions
|
|
* [1993/04/29 20:54:21 marty]
|
|
*
|
|
* Revision 1.5.1.23 1993/04/29 17:54:40 damon
|
|
* CR 135. Fixed sci_diff_rev_with_file
|
|
* [1993/04/29 17:54:05 damon]
|
|
*
|
|
* Revision 1.5.1.22 1993/04/29 15:45:27 damon
|
|
* CR 463. More pedantic changes
|
|
* [1993/04/29 15:44:31 damon]
|
|
*
|
|
* Revision 1.5.1.21 1993/04/29 14:25:35 damon
|
|
* CR 463. Pedantic changes
|
|
* [1993/04/29 14:25:10 damon]
|
|
*
|
|
* Revision 1.5.1.20 1993/04/28 14:35:27 damon
|
|
* CR 463. More pedantic changes
|
|
* [1993/04/28 14:34:28 damon]
|
|
*
|
|
* Revision 1.5.1.19 1993/04/26 19:23:34 damon
|
|
* CR 428. CR 411. CR 135. ODE 2.2.1 patches
|
|
* [1993/04/26 19:21:46 damon]
|
|
*
|
|
* Revision 1.5.1.18 1993/04/26 16:24:15 damon
|
|
* CR 407. Made rco/co rdiff/diff explainations better
|
|
* [1993/04/26 16:24:01 damon]
|
|
*
|
|
* Revision 1.5.1.17 1993/04/26 16:02:01 damon
|
|
* CR 401. Removed varargs
|
|
* [1993/04/26 16:01:39 damon]
|
|
*
|
|
* Revision 1.5.1.16 1993/04/26 15:26:00 damon
|
|
* CR 436. Merged with martys changes
|
|
* [1993/04/26 15:25:10 damon]
|
|
*
|
|
* CR 436. Now using ode2.3_server_base directory for sc.conf
|
|
* *
|
|
* Revision 1.5.1.15 1993/04/21 21:48:51 marty
|
|
* Cleaning up memory leaks.
|
|
* [1993/04/21 21:46:08 marty]
|
|
* *
|
|
* Revision 1.5.1.14 1993/04/16 15:39:55 damon
|
|
* CR 436. Synching create_branch code
|
|
* [1993/04/16 15:39:37 damon]
|
|
* *
|
|
* Revision 1.5.1.13 1993/04/09 17:22:45 damon
|
|
* CR 446. Remove warnings with added includes
|
|
* [1993/04/09 17:21:54 damon]
|
|
*
|
|
* Revision 1.5.1.12 1993/04/09 14:25:16 damon
|
|
* Merged with Martys changes
|
|
* [1993/04/09 14:24:43 damon]
|
|
*
|
|
* CR 432. sci_outdate_list_p1 now calls src_ctl_outdate
|
|
* [1993/04/09 14:22:09 damon]
|
|
*
|
|
* CR 446. Clean up include files
|
|
*
|
|
* Revision 1.5.1.11 1993/04/06 23:48:49 marty
|
|
* Cleanup real_check_in() routine to free up unneeded allocated space.
|
|
* [1993/04/06 23:44:24 marty]
|
|
*
|
|
* Revision 1.5.1.10 1993/04/01 17:05:01 marty
|
|
* Remove extra odexm_open() from sci_fast_lookup_revision().
|
|
* [1993/04/01 17:04:40 marty]
|
|
*
|
|
* Revision 1.5.1.9 1993/03/31 19:06:29 damon
|
|
* CR 443. opentemp now just creates directory, no file
|
|
* [1993/03/31 19:05:53 damon]
|
|
*
|
|
* Revision 1.5.1.8 1993/03/30 20:44:38 damon
|
|
* CR 436. Made ancestry update for bmerge better
|
|
* [1993/03/30 20:44:08 damon]
|
|
*
|
|
* Revision 1.5.1.7 1993/03/26 18:02:16 marty
|
|
* Fix bug with argument passing to src_ctl_fast_lookup_revision().
|
|
* [1993/03/26 18:00:41 marty]
|
|
*
|
|
* Revision 1.5.1.6 1993/03/25 21:19:07 marty
|
|
* Added sci_lookup_fast_rev_list() for quick revision
|
|
* lookup of a large group of files.
|
|
* [1993/03/25 21:18:44 marty]
|
|
*
|
|
* Revision 1.5.1.5 1993/03/24 20:49:42 damon
|
|
* CR 436. Added remove and resub options
|
|
* [1993/03/24 20:38:16 damon]
|
|
*
|
|
* Revision 1.5.1.4 1993/03/22 22:17:34 marty
|
|
* Added comment_leader to all calls of src_ctl_branch_create(). Removed
|
|
* call to sci_set_comment_leader() in sci_create_files().
|
|
* [1993/03/22 22:14:08 marty]
|
|
*
|
|
* Revision 1.5.1.3 1993/03/19 15:51:56 marty
|
|
* Added NULL as last argument in odexm commands in sci_outdate_list()
|
|
* and sci_set_comment_leader() to work with client/server model.
|
|
* [1993/03/19 15:51:15 marty]
|
|
*
|
|
* Revision 1.5.1.2 1993/03/17 21:15:05 damon
|
|
* Making sure merge to trunk worked
|
|
* [1993/03/17 21:14:45 damon]
|
|
*
|
|
* Revision 1.5.1.1 1993/03/17 21:11:23 devrcs
|
|
* Move to trunk for speed step 2
|
|
*
|
|
* Revision 1.5 1993/03/17 21:10:10 devrcs
|
|
* Move to trunk for speed step 1
|
|
*
|
|
* Revision 1.4.5.35 1993/03/17 20:41:52 damon
|
|
* CR 446. Fixed include files/ forward decls.
|
|
* [1993/03/17 20:41:22 damon]
|
|
*
|
|
* Revision 1.4.5.34 1993/03/17 19:40:45 damon
|
|
* CR 432. Added src_ctl_set_ancestry for merges
|
|
* [1993/03/17 19:39:21 damon]
|
|
*
|
|
* CR 436. Tidy up temp file creation
|
|
*
|
|
* Revision 1.4.5.33 1993/03/17 16:13:12 damon
|
|
* CR 436. Tidy up temp file creation
|
|
* [1993/03/17 16:12:52 damon]
|
|
*
|
|
* Revision 1.4.5.32 1993/03/17 16:06:31 marty
|
|
* Change alloc_comment_leader() so that gmatch() is called
|
|
* with a filename, not a pathname. This is done by using
|
|
* path().
|
|
* [1993/03/17 16:06:01 marty]
|
|
*
|
|
* Revision 1.4.5.31 1993/03/16 21:26:54 marty
|
|
* Allow src_ctl_diff_rev_with_file to operate on regular files (weed
|
|
* out the symbolic links) for OT# 69
|
|
* [1993/03/16 21:26:26 marty]
|
|
*
|
|
* Revision 1.4.5.30 1993/03/16 19:04:34 marty
|
|
* Removed getenv() call, replaced it with call to get_rc_value().
|
|
* Also type cast alot of function calls to get rid of warnings.
|
|
* [1993/03/16 18:59:02 marty]
|
|
*
|
|
* Revision 1.4.5.29 1993/03/15 21:41:59 marty
|
|
* Change alloc_comment_leader to match project defined comment
|
|
* leaders defined in the COMMENT_LEADERS variable.
|
|
* [1993/03/15 21:39:23 marty]
|
|
*
|
|
* Revision 1.4.5.28 1993/03/15 19:26:48 marty
|
|
* Ensure that the user has a branch on the file before trying
|
|
* to "undo" it.
|
|
* [1993/03/15 19:25:52 marty]
|
|
*
|
|
* Revision 1.4.5.27 1993/03/15 19:12:12 marty
|
|
* When "undo"ing a bcreate, indicate that no lock was set.
|
|
* [1993/03/15 19:10:44 marty]
|
|
*
|
|
* Revision 1.4.5.26 1993/03/15 18:13:56 damon
|
|
* CR 436. Changed call to read_legal_copyrights
|
|
* [1993/03/15 18:13:41 damon]
|
|
*
|
|
* Revision 1.4.5.25 1993/03/15 18:10:20 damon
|
|
* CR 436. Added sci_submit
|
|
* [1993/03/15 18:09:49 damon]
|
|
*
|
|
* Revision 1.4.5.23 1993/03/15 15:53:09 marty
|
|
* Change sequence of calls inscrc_ctl_merge() when using
|
|
* hst_* routines.
|
|
* [1993/03/15 15:52:38 marty]
|
|
*
|
|
* Revision 1.4.5.22 1993/03/05 16:04:26 marty
|
|
* Check status of src_ctl_check_in() before updating history
|
|
* of the file. On error don't update history.
|
|
* [1993/03/05 16:00:45 marty]
|
|
*
|
|
* Revision 1.4.5.21 1993/03/04 21:45:43 damon
|
|
* CR 436. Added sci_add_to_list_as_is
|
|
* [1993/03/04 20:02:03 damon]
|
|
*
|
|
* Revision 1.4.5.20 1993/03/04 20:25:11 marty
|
|
* Added calls to history manipulation routines for src_ctl_merge and
|
|
* real_check_in_file().
|
|
* [1993/03/04 20:24:28 marty]
|
|
*
|
|
* Added routines split_files and join_files.
|
|
* [1993/02/24 15:00:18 marty]
|
|
*
|
|
* Revision 1.4.5.19 1993/02/19 22:42:00 marty
|
|
* Remove lock_sb() call from sci_init().
|
|
* [1993/02/19 22:40:16 marty]
|
|
* Working Version 1
|
|
*
|
|
* Revision 1.4.5.18 1993/02/19 17:35:50 damon
|
|
* CR 193
|
|
* sci_edit_files assumes sci_lookup_user_rev_list has
|
|
* already been called.
|
|
* [1993/02/19 17:31:30 damon]
|
|
*
|
|
* Revision 1.4.5.17 1993/02/11 21:07:12 damon
|
|
* CR 390. Changed rcs -o- to rcs -o:
|
|
* [1993/02/11 21:06:48 damon]
|
|
*
|
|
* Revision 1.4.5.16 1993/02/11 19:56:25 damon
|
|
* CR 432. Now calls outdate instead of rcs -o
|
|
* [1993/02/11 19:56:03 damon]
|
|
*
|
|
* Revision 1.4.5.15 1993/02/10 18:34:44 damon
|
|
* CR 432. Tracks simple ancestry
|
|
* [1993/02/10 18:34:11 damon]
|
|
*
|
|
* Revision 1.4.5.14 1993/02/06 21:20:47 damon
|
|
* CR 429. Added sci_undo_submit
|
|
* [1993/02/06 21:18:46 damon]
|
|
*
|
|
* Revision 1.4.5.13 1993/02/04 21:18:32 damon
|
|
* CR 230. Changed rename back to copy_file in sci_update_build_list
|
|
* [1993/02/04 21:16:04 damon]
|
|
*
|
|
* Revision 1.4.5.12 1993/02/04 21:02:12 damon
|
|
* Fixing submission problem
|
|
* [1993/02/04 21:01:54 damon]
|
|
*
|
|
* Revision 1.4.5.11 1993/02/03 15:50:32 damon
|
|
* CR 230
|
|
* BCSTEMP now defaults to <sandbox base><sandbox>/tmp.
|
|
* Movement of files from the tmp directory into the
|
|
* sandbox is now handled by rename instead of copy_file.
|
|
* [1993/02/03 15:50:07 damon]
|
|
*
|
|
* Revision 1.4.5.10 1993/02/01 21:54:55 damon
|
|
* CR 417. Uses sc.conf file instead of local and shared
|
|
* [1993/02/01 21:53:45 damon]
|
|
*
|
|
* Revision 1.4.5.9 1993/01/26 16:34:42 damon
|
|
* CR 396. Conversion to err_log
|
|
* [1993/01/26 16:34:04 damon]
|
|
*
|
|
* Revision 1.4.5.8 1993/01/25 21:28:19 damon
|
|
* CR 396. Converted history.c to err_log
|
|
* [1993/01/25 21:26:51 damon]
|
|
*
|
|
* Revision 1.4.5.7 1993/01/21 20:36:13 damon
|
|
* CR 197. Fixed logic for -ko in sci_set_comment_leader
|
|
* [1993/01/21 20:35:37 damon]
|
|
*
|
|
* Revision 1.4.5.6 1993/01/21 00:06:23 damon
|
|
* CR 382. Removed cruft
|
|
* [1993/01/21 00:04:36 damon]
|
|
*
|
|
* Revision 1.4.5.5 1993/01/20 22:21:27 damon
|
|
* CR 376. Moved more code out from sci.c
|
|
* [1993/01/20 22:16:11 damon]
|
|
*
|
|
* Revision 1.4.5.4 1993/01/18 20:39:47 damon
|
|
* CR 197. Fixed keyword expansion for BIN/NONE
|
|
* [1993/01/18 20:35:55 damon]
|
|
*
|
|
* Revision 1.4.5.3 1993/01/15 16:13:18 damon
|
|
* CR 376. Renamed from sci_rcs.c
|
|
* [1993/01/15 15:50:50 damon]
|
|
*
|
|
* Revision 1.4.5.2 1993/01/13 17:52:03 damon
|
|
* CR 196. Removed rcs locking
|
|
* [1993/01/13 17:51:09 damon]
|
|
*
|
|
* Revision 1.4.1.19 1992/12/18 18:58:46 damon
|
|
*
|
|
* ODE 2.2
|
|
* CR 365. Does not call okmesg if NONE or BIN
|
|
* CR 370. Added -common functionality
|
|
* CR 362. bci -m works without -auto
|
|
* CR 361. Now warns about checking out defunct file
|
|
* CR 357 356. Now creates missing directories for bcreate/bco
|
|
* CR 333. fixed call to copy_file
|
|
* CR 345. Removed ability to check-out defunct file
|
|
* ODE 2.2 CR 183. Added CMU notice
|
|
* CR 342. Added sci_set_symbol_list
|
|
* CR 331. Fixed src_ctl_show_log for blog
|
|
* CR 335. Added checks for NONE and BIN to remove
|
|
* CR 333. Fixed calls to copy_file
|
|
* Replaced comparison with NULL to '\0'
|
|
* CR 291. Fixed renumbered av array in create_leaderless_log
|
|
* CR 328. Removed extraneous debug code
|
|
* CR 329. Made more portable
|
|
* CR 296. Added a forward decl. for src_ctl_config_remove
|
|
* CR 119. Now handles multiple locks
|
|
* CR 319. Added checks for *_relay
|
|
* CR 177. Fixed ordering of MA_LEADER and MA_HELP
|
|
* CR 321. Added sandbox locking
|
|
* CR 299. Converted create_leaderless_log to odexm
|
|
* CR 238. Adjusted for bco
|
|
* CR 238. Fixed sci_create_files for bcreate
|
|
* CR 238. Added diff functions
|
|
* CR282: Made more portable to non-BSD systems.
|
|
* CR 238. Removed some debugging statements.
|
|
* CR 238. Cleaned up function declarations
|
|
* CR 240. Added odexm initialization
|
|
* DCE OT defect 2341.
|
|
* CR 238. Fixed sci_show_log_list
|
|
* CR 191 checklogstate and supporting functions are
|
|
* now only in libode.
|
|
*
|
|
* Revision 1.3.2.4 1992/06/15 19:23:43 damon
|
|
* Synched with DCE changes
|
|
* [1992/06/15 19:21:03 damon]
|
|
*
|
|
* Copied from ODE latest
|
|
* Used to skip looking up latest revisions during resubmissions which
|
|
* caused (null) to be used for a revision if a submission was
|
|
* interrupted during the build update stage. This affected the SNAPSHOT
|
|
* file and the *log files.
|
|
*
|
|
* Now closes files when there is a problem with the logs
|
|
* [1992/03/09 19:12:00 damon]
|
|
*
|
|
* Revision 1.3 1991/12/17 21:01:18 devrcs
|
|
* Ported to hp300_hpux
|
|
* [1991/12/17 14:31:54 damon]
|
|
*
|
|
* Revision 1.2 1991/12/05 21:12:59 devrcs
|
|
* New file for ODE 2.1. Currently only supports bsubmit.
|
|
* Will be split into more files later.
|
|
*
|
|
* History extraction is now less picky about comment leaders as below
|
|
*
|
|
* checklogstate now strips any trailing whitespace from the comment leader
|
|
*
|
|
* Made /tmp into DEF_TMPDIR
|
|
*
|
|
* Added checks for binary file (if leader is "BIN"). If
|
|
* binary, do not do merge.
|
|
*
|
|
* Added canonicalization to deal with /..//./ stuff in paths.
|
|
*
|
|
* Now uses rlog -h instead of rlog -i to search for locks.
|
|
* No longer tries to generate log messages for defuncted files.
|
|
* Removed duplicate declaration of BCSBBASE.
|
|
*
|
|
* Cleaned up error handling. Added log_error and is_in_error to
|
|
* handle special cases where ERROR and OK can't be returned
|
|
* directly.
|
|
*
|
|
* $EndLog$
|
|
*/
|
|
/*
|
|
* This module provides the following functions:
|
|
*
|
|
* sci_init
|
|
* sci_lookup_leader_list
|
|
* sci_all_list
|
|
* sci_lookup_user_rev_list
|
|
* sci_lookup_latest_rev_list
|
|
* sci_ancestor_list
|
|
* sci_locked_list
|
|
* sci_is_branch
|
|
* sci_check_in_list
|
|
* sci_lock_list
|
|
* sci_update_build_list
|
|
* sci_outdate_list
|
|
* sci_add_to_list
|
|
* sci_trackfile
|
|
*/
|
|
#ifndef lint
|
|
static char sccsid[] = "@(#)20 1.1 src/bldenv/sbtools/libode/sci.c, bldprocess, bos412, GOLDA411a 1/19/94 17:42:29";
|
|
#endif /* not lint */
|
|
|
|
#if !defined(lint) && !defined(_NOIDENT)
|
|
static char rcsid[] = "@(#)$RCSfile: sci.c,v $ $Revision: 1.5.7.21 $ (OSF) $Date: 1993/12/02 22:01:44 $";
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <utime.h>
|
|
#include <unistd.h>
|
|
#include <ode/copyrights.h>
|
|
#include <ode/errno.h>
|
|
#include <ode/history.h>
|
|
#include <ode/interface.h>
|
|
#include <ode/misc.h>
|
|
#include <ode/odedefs.h>
|
|
#include <ode/odexm.h>
|
|
#include <ode/project.h>
|
|
#include <ode/public/error.h>
|
|
#include <ode/public/odexm_client.h>
|
|
#include <ode/parse_rc_file.h>
|
|
#include <ode/run.h>
|
|
#include <ode/sandboxes.h>
|
|
#include <ode/sci.h>
|
|
#include <ode/sets.h>
|
|
#include <ode/src_ctl_rcs.h>
|
|
#include <ode/util.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
|
|
#define TMPMODE 0777 /* mode for temporary working file */
|
|
#define LOGMODE 0644 /* mode for temporary message file */
|
|
#define LOGPROMPT "<<<replace with log message"
|
|
#define LOGMSGSIZE 4096 /* -m<msg> buffer size */
|
|
/* comment syntax for C files */
|
|
#ifndef DEF_EDITOR
|
|
# define DEF_EDITOR "vi" /* default editor */
|
|
#endif
|
|
|
|
|
|
#define ATOI(n, p) \
|
|
(n) = 0; \
|
|
if ('0' > *(p) || *(p) > '9') \
|
|
return(1); \
|
|
while ('0' <= *(p) && *(p) <= '9') { \
|
|
(n) = (n) * 10 + (*(p) - '0'); \
|
|
(p)++; \
|
|
}
|
|
|
|
/*
|
|
* GLOBAL VARIABLES:
|
|
*/
|
|
int sci_local = FALSE;
|
|
|
|
#define MAX_MONITORS 3
|
|
#define RCS_MONITOR 0
|
|
#define SRC_MONITOR 1
|
|
#define LOGS_MONITOR 2
|
|
OXMINIT oxminit [MAX_MONITORS];
|
|
|
|
OXM_CNXTN rcs_monitor;
|
|
OXM_CNXTN src_monitor;
|
|
|
|
extern int valid_copyrights;
|
|
extern char * copyright_name[];
|
|
extern char * raw_copyright_list[];
|
|
char *copyright_years;
|
|
|
|
STATIC
|
|
int file_mode = 0;
|
|
|
|
STATIC
|
|
int submitting = FALSE;
|
|
|
|
STATIC
|
|
const char * org_path;
|
|
|
|
char * src_path;
|
|
|
|
STATIC
|
|
const char * EDIT_PROG;
|
|
|
|
char temp1[MAXPATHLEN], temp2[MAXPATHLEN], temp3[MAXPATHLEN];
|
|
STATIC
|
|
char temp4[MAXPATHLEN], temp5[MAXPATHLEN];
|
|
STATIC
|
|
int temp_merge_setup = FALSE;
|
|
|
|
char mesgfile[MAXPATHLEN]; /* temporary file for log message */
|
|
|
|
STATIC
|
|
char *rcfile_source_host;
|
|
STATIC
|
|
char *rcfile_rcs_host;
|
|
|
|
char *BCSTEMP; /* R */
|
|
char *BCSSET_NAME; /* R/W */
|
|
STATIC
|
|
char *USER; /* R */
|
|
|
|
STATIC
|
|
char bcsconfig[MAXPATHLEN]; /* bcs config file */
|
|
STATIC
|
|
char bcsset[MAXPATHLEN]; /* bcs set file */
|
|
char bcslog[MAXPATHLEN]; /* bcs log file */
|
|
STATIC
|
|
char bcspath[MAXPATHLEN]; /* bcs path file */
|
|
STATIC
|
|
char bcstempbuf[MAXPATHLEN]; /* buffer for generated BCSTEMP */
|
|
STATIC
|
|
char trackfile[MAXPATHLEN]; /* path and name of tracking file */
|
|
|
|
char working_file[MAXPATHLEN];
|
|
STATIC
|
|
char working_file_dir[MAXPATHLEN];
|
|
char working_file_tail[MAXPATHLEN];
|
|
char canon_working_file[MAXPATHLEN];
|
|
char temp_working_file[MAXPATHLEN];
|
|
|
|
STATIC
|
|
int usetrunk; /* using trunk directly */
|
|
STATIC
|
|
char setrev[MAXPATHLEN]; /* set revision */
|
|
|
|
/*
|
|
* PROTOTYPES
|
|
*/
|
|
|
|
STATIC
|
|
src_ctl_set_remove( SCI_ELEM );
|
|
|
|
STATIC
|
|
void set_cleanup( void );
|
|
|
|
BOOLEAN
|
|
confirm_alloc ( SCI_LIST );
|
|
|
|
int
|
|
real_check_in_file ( SCI_ELEM , char * , char * ,
|
|
BOOLEAN );
|
|
|
|
void
|
|
sci_read_file ( char * , char * , char ** , BOOLEAN * , ERR_LOG * );
|
|
|
|
int
|
|
temp_func ( SCI_ELEM sci_ptr );
|
|
|
|
/*
|
|
* FUNCTIONS/PROCEDURES
|
|
*/
|
|
|
|
int
|
|
get_src_and_org_paths ( char * sb_base, char * sb )
|
|
|
|
/* This procedure determines the source directory for the user
|
|
and then does a cd to it. First, however, it finds out where
|
|
the user is and sets up the current directory. This is used
|
|
for searching for paths for files to submit later. */
|
|
|
|
{
|
|
char * src_dir, /* points to string with source dir */
|
|
* ptr_org, /* misc string pointer */
|
|
tmpdir [ PATH_LEN ], /* misc string */
|
|
tmpdir2 [ PATH_LEN ]; /* misc string */
|
|
|
|
concat ( tmpdir, sizeof (tmpdir), sb_base, "/", sb, "/src", NULL );
|
|
src_dir = strdup ( tmpdir );
|
|
if ( *src_dir != SLASH )
|
|
uquit ( ERROR, FALSE,
|
|
"\tvalue of %s field does not begin with a %c.\n", SOURCE_BASE, SLASH );
|
|
|
|
if (( isdir ( src_dir ) == ERROR ))
|
|
uquit ( ERROR, FALSE, "\tno source directory, %s, in sandbox.\n", src_dir );
|
|
|
|
if ( getcwd ( tmpdir, sizeof(tmpdir) ) == NULL )
|
|
uquit ( ERROR, FALSE, "\tgetcwd: %s.\n", strerror(errno) );
|
|
chdir ( src_dir );
|
|
|
|
if ( getcwd ( tmpdir2, sizeof(tmpdir2) ) == NULL )
|
|
uquit ( ERROR, FALSE, "\tgetcwd: %s.\n", strerror(errno) );
|
|
|
|
if (src_dir != NULL)
|
|
free (src_dir);
|
|
src_dir = strdup ( tmpdir2 );
|
|
|
|
if ( strncmp ( src_dir, tmpdir, strlen ( src_dir )) != 0 ) {
|
|
ui_print ( VFATAL, "current directory not in source base: %s.\n",
|
|
src_dir);
|
|
return ( ERROR );
|
|
} /* if */
|
|
ptr_org = tmpdir + strlen ( src_dir );
|
|
/* going to skip front part */
|
|
if ( *ptr_org != SLASH ) {
|
|
org_path = "./";
|
|
} else {
|
|
while ( *ptr_org == SLASH )
|
|
ptr_org++;
|
|
|
|
concat ( tmpdir2, sizeof(tmpdir2), "./", ptr_org, NULL );
|
|
org_path = strdup ( tmpdir2 );
|
|
} /* if */
|
|
src_path = strdup ( src_dir );
|
|
return ( OK );
|
|
} /* end get_src_path */
|
|
|
|
/*
|
|
* Generate the full path and name for a given set
|
|
*/
|
|
int full_set_name ( char ** fsn, char * set_name )
|
|
{
|
|
char tmp_name1 [ PATH_LEN ]; /* misc string */
|
|
|
|
/*
|
|
* Not sure what this next statement does
|
|
if ((( *set_name < 'A' ) || ( *set_name > 'Z' )) &&
|
|
( strncmp ( tmp_name, set_name, ptr - tmp_name )))
|
|
*/
|
|
/*
|
|
* Not sure what this next statement does
|
|
else
|
|
strcpy ( set_file_name, set_name );
|
|
*/
|
|
/* end if */
|
|
|
|
concat ( tmp_name1, NAME_LEN, BCS_SET, set_name, NULL );
|
|
*fsn = strdup ( tmp_name1 );
|
|
if ( *fsn == NULL)
|
|
return ( ERROR );
|
|
else
|
|
return ( OK );
|
|
/* end if */
|
|
}
|
|
|
|
int
|
|
bcreate_undo( SCI_ELEM sci_ptr, char * set_name )
|
|
/*
|
|
* routine to undo a file just created
|
|
*/
|
|
{
|
|
int status;
|
|
ERR_LOG log;
|
|
|
|
/*
|
|
* if the source control info does not exist, then abort
|
|
*/
|
|
status = src_ctl_file_exists( sci_ptr -> name, &log );
|
|
|
|
if (status == ERROR )
|
|
return( ERROR );
|
|
if (status == 1) {
|
|
ui_print ( VFATAL, "[ source control information does not exist ]\n");
|
|
return( ERROR );
|
|
}
|
|
|
|
/*
|
|
* undo create operation
|
|
*/
|
|
if (sci_ptr->ver_user != NULL)
|
|
log = (ERR_LOG) src_ctl_undo_create( sci_ptr -> name,
|
|
sci_ptr -> ver_user, FALSE );
|
|
|
|
if (log != OE_OK)
|
|
return( ERROR );
|
|
|
|
/*
|
|
* remove the branch symbol
|
|
*/
|
|
if (sci_ptr->ver_user != NULL) {
|
|
log = (ERR_LOG) src_ctl_remove_symbol( sci_ptr -> name, BCSSET_NAME );
|
|
if (log != OE_OK)
|
|
return( ERROR );
|
|
}
|
|
|
|
/*
|
|
* If the rcs file is empty, then remove it.
|
|
*/
|
|
log = (ERR_LOG) src_ctl_remove_file( sci_ptr -> name );
|
|
|
|
|
|
/*
|
|
* update set file,
|
|
* then delete working file from sandbox
|
|
*/
|
|
(void) src_ctl_set_remove ( sci_ptr );
|
|
if (unlink(working_file) == 0 )
|
|
ui_print ( VNORMAL, "rm: removing %s\n", working_file);
|
|
/* if */
|
|
return( OK );
|
|
}
|
|
|
|
/*
|
|
* START OF SCI_* PROCEDURES
|
|
*/
|
|
|
|
BOOLEAN sci_has_log ( SCI_ELEM sci_ptr )
|
|
{
|
|
return ( strcmp ( sci_ptr -> leader, "NONE" ) != 0 &&
|
|
strcmp ( sci_ptr -> leader, "BIN" ) != 0 );
|
|
} /* end sci_has_log */
|
|
|
|
ERR_LOG
|
|
sci_ancestor_update_list( SCI_LIST sl )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char * ancestry;
|
|
ERR_LOG log;
|
|
char new_ancestry[MAXPATHLEN];
|
|
int len;
|
|
int len2;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( err_log ( OE_ALLOC) );
|
|
/* end if */
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
len = strlen(sci_ptr -> ancestry );
|
|
concat ( new_ancestry, sizeof(new_ancestry), sci_ptr -> ver_user, ">",
|
|
sci_ptr -> ver_merge, NULL );
|
|
len2 = len + strlen (new_ancestry);
|
|
ancestry = (char *)malloc(len2);
|
|
concat ( ancestry, len2, new_ancestry,";", sci_ptr -> ancestry, NULL );
|
|
free ( sci_ptr -> ancestry );
|
|
sci_ptr -> ancestry = ancestry;
|
|
src_ctl_add_ancestry ( sci_ptr -> name, new_ancestry );
|
|
}
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
return( log );
|
|
} /* sci_ancestor_update_list */
|
|
|
|
ERR_LOG
|
|
sci_ancestor_update_list2 ( SCI_LIST sl )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char * ancestry;
|
|
ERR_LOG log;
|
|
char new_ancestry[MAXPATHLEN];
|
|
int len;
|
|
int len2;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( err_log ( OE_ALLOC) );
|
|
/* end if */
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
src_ctl_get_ancestry ( sci_ptr -> name, &(sci_ptr -> ancestry) );
|
|
len = strlen(sci_ptr -> ancestry );
|
|
concat ( new_ancestry, sizeof(new_ancestry), sci_ptr -> ver_user, ">",
|
|
sci_ptr -> ver_config, NULL );
|
|
len2= len + strlen ( new_ancestry );
|
|
ancestry = (char *)malloc(len2);
|
|
concat ( ancestry, len2, new_ancestry, ";", sci_ptr -> ancestry, NULL );
|
|
free ( sci_ptr -> ancestry );
|
|
sci_ptr -> ancestry = ancestry;
|
|
src_ctl_add_ancestry ( sci_ptr -> name, new_ancestry );
|
|
}
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
return( log );
|
|
} /* sci_ancestor_update_list2 */
|
|
|
|
int
|
|
makedir( char *dir )
|
|
{
|
|
char dbuf[MAXPATHLEN];
|
|
char *ptr;
|
|
|
|
ptr = concat(dbuf, sizeof(dbuf), dir, NULL);
|
|
if (*(ptr-1) != '/')
|
|
*ptr++ = '/';
|
|
*ptr++ = '.';
|
|
*ptr++ = '\0';
|
|
return(makepath(dbuf, NULL, TRUE, TRUE));
|
|
} /* end makedir */
|
|
|
|
int
|
|
simple_cmp_func( char *str1, char *str2, int arg, int *skipped )
|
|
{
|
|
int cmp;
|
|
cmp = strcmp(str1, str2);
|
|
if (cmp == 0)
|
|
*skipped = TRUE;
|
|
return(cmp);
|
|
} /* end simple_cmp_func */
|
|
|
|
|
|
/*
|
|
* This is rather archaic, and should be re-done, but it
|
|
* is okay for now.
|
|
*/
|
|
STATIC
|
|
int check_path( char *w )
|
|
{
|
|
char dbuf[MAXPATHLEN], fbuf[MAXPATHLEN];
|
|
char *ptr;
|
|
|
|
/*
|
|
* first we check the working file
|
|
*/
|
|
enter ( "check_path" );
|
|
path(w, dbuf, fbuf);
|
|
(void) strcpy(working_file_dir, dbuf);
|
|
if (*fbuf == '.' && *(fbuf+1) == '\0') {
|
|
ui_print ( VFATAL, ".: invalid directory\n");
|
|
return( ERROR );
|
|
}
|
|
if (*dbuf == '.' && *(dbuf+1) == '\0')
|
|
*dbuf = '\0';
|
|
else {
|
|
if (*dbuf == '.' && *(dbuf+1) == '/')
|
|
(void) strcpy(dbuf, dbuf+2);
|
|
ptr = dbuf + strlen(dbuf);
|
|
*ptr++ = '/';
|
|
*ptr = '\0';
|
|
}
|
|
(void) strcpy(working_file, w);
|
|
(void) strcpy(working_file_tail, fbuf);
|
|
(void) concat(canon_working_file, sizeof(canon_working_file),
|
|
"./", dbuf, fbuf, NULL);
|
|
(void) concat(temp_working_file, sizeof(temp_working_file),
|
|
BCSTEMP, "/", fbuf, NULL);
|
|
leave ( );
|
|
|
|
return( OK );
|
|
} /* check_path */
|
|
|
|
|
|
STATIC
|
|
int set_insert(void )
|
|
{
|
|
char cwbuf[MAXPATHLEN];
|
|
|
|
(void) concat(cwbuf, sizeof(cwbuf), canon_working_file, "\n", NULL);
|
|
return(insert_line_in_sorted_file(bcsset, cwbuf,
|
|
(int (*) (char *, ... ) )simple_cmp_func, 0));
|
|
} /* end set_insert */
|
|
|
|
|
|
STATIC
|
|
int remove_working_file( BOOLEAN local )
|
|
{
|
|
int i;
|
|
int status;
|
|
const char *av[16];
|
|
ERR_LOG log;
|
|
|
|
if (local ) {
|
|
(void) unlink(working_file);
|
|
return( OK );
|
|
}
|
|
i = 0;
|
|
av[i++] = "rm";
|
|
av[i++] = "-f";
|
|
av[i++] = canon_working_file;
|
|
log = oxm_runcmd ( src_monitor, i, av, NULL );
|
|
log = oxm_endcmd ( src_monitor, &status );
|
|
if ( status != 0 )
|
|
return( ERROR );
|
|
return( OK );
|
|
} /* end remove_working_file */
|
|
|
|
|
|
STATIC
|
|
int copy_file ( char *src, char *dst,
|
|
BOOLEAN local )
|
|
/* local file copy? If FALSE, dst is on another machine */
|
|
{
|
|
char tmp[MAXPATHLEN];
|
|
int sfd;
|
|
int tfd;
|
|
struct utimbuf tv;
|
|
struct stat st, statb;
|
|
ERR_LOG log;
|
|
|
|
ui_print ( VDEBUG, "Entering copy_file\n" );
|
|
ui_print ( VDEBUG, "src :%s:\n", src );
|
|
ui_print ( VDEBUG, "dst :%s:\n", dst );
|
|
if (stat(src, &st) < 0) {
|
|
ui_print ( VFATAL, "stat '%s' \n", src);
|
|
return( ERROR );
|
|
}
|
|
if ( ! local ) {
|
|
int status;
|
|
int i;
|
|
const char *av[16];
|
|
i = 0;
|
|
av[i++] = "-t1";
|
|
av[i++] = "1";
|
|
av[i++] = "odexm_cp";
|
|
av[i++] = src;
|
|
av[i++] = canon_working_file;
|
|
log = oxm_runcmd ( src_monitor, i, av, NULL );
|
|
log = oxm_endcmd ( src_monitor, &status );
|
|
if (status != 0)
|
|
return( ERROR );
|
|
return( OK );
|
|
}
|
|
sfd = open(src, O_RDONLY, 0);
|
|
if (sfd < 0) {
|
|
ui_print ( VFATAL, "open %s\n", src);
|
|
return( ERROR );
|
|
}
|
|
(void) concat(tmp, sizeof(tmp), dst, ".tmp", NULL);
|
|
(void) unlink(tmp);
|
|
tfd = open(tmp, O_WRONLY|O_CREAT|O_EXCL, 0600);
|
|
if (tfd < 0 && strcmp( dst, working_file) == 0 ) {
|
|
if (stat(working_file_dir, &statb) < 0) {
|
|
if (makedir(working_file_dir) != 0)
|
|
return( ERROR );
|
|
} else if ((statb.st_mode&S_IFMT) != S_IFDIR) {
|
|
ui_print ( VFATAL, "%s: not a directory\n", working_file_dir);
|
|
return( ERROR );
|
|
}
|
|
tfd = open(tmp, O_WRONLY|O_CREAT|O_EXCL, 0600);
|
|
}
|
|
if (tfd < 0) {
|
|
ui_print ( VFATAL, "open %s\n", tmp);
|
|
(void) close(sfd);
|
|
return( ERROR );
|
|
}
|
|
if (filecopy(sfd, tfd) < 0) {
|
|
ui_print ( VFATAL, "filecopy %s to %s failed\n", src, tmp);
|
|
(void) close(sfd);
|
|
(void) close(tfd);
|
|
(void) unlink(tmp);
|
|
return( ERROR );
|
|
}
|
|
if (close(sfd) < 0) {
|
|
ui_print ( VFATAL, "close %s\n", src);
|
|
(void) close(tfd);
|
|
(void) unlink(tmp);
|
|
return( ERROR );
|
|
}
|
|
if (close(tfd) < 0) {
|
|
ui_print ( VFATAL, "close %s\n", tmp);
|
|
(void) close(tfd);
|
|
(void) unlink(tmp);
|
|
return( ERROR );
|
|
}
|
|
if (chmod(tmp, (int)st.st_mode&0777) < 0) {
|
|
ui_print ( VFATAL, "chmod %s\n", tmp);
|
|
(void) unlink(tmp);
|
|
return( ERROR );
|
|
}
|
|
tv.actime = st.st_atime;
|
|
tv.modtime = st.st_mtime;
|
|
if (utime(tmp, &tv) < 0) {
|
|
ui_print ( VFATAL, "utime %s\n", tmp);
|
|
(void) unlink(tmp);
|
|
return( ERROR );
|
|
}
|
|
if (rename(tmp, dst) < 0) {
|
|
ui_print ( VFATAL, "2 rename %s to %s failed\n", tmp, dst);
|
|
return( ERROR );
|
|
}
|
|
ui_print ( VDEBUG, "Leaving copy_file\n" );
|
|
return( OK );
|
|
} /* end copy_file */
|
|
|
|
/*
|
|
* This procedure either creates or updates the tracking file.
|
|
* It makes sure a new entry is put in the file in the appropriate
|
|
* place to remain sorted.
|
|
*/
|
|
STATIC
|
|
int track_insert ( char * file_name )
|
|
{
|
|
char cwbuf[MAXPATHLEN];
|
|
|
|
(void) concat(cwbuf, sizeof(cwbuf), file_name, "\n", NULL);
|
|
return(insert_line_in_sorted_file(trackfile, cwbuf,
|
|
(int (*) (char *, ... ) ) simple_cmp_func, 0));
|
|
}
|
|
|
|
/*
|
|
* log_error and is_in_error are temporary place holders
|
|
* for more comprehensive error handling routines.
|
|
* They are only necessary for a few routines.
|
|
*/
|
|
|
|
int global_status = OK;
|
|
|
|
void log_error ( void )
|
|
{
|
|
global_status = ERROR;
|
|
} /* end log_error */
|
|
|
|
|
|
BOOLEAN is_in_error ( void )
|
|
{
|
|
return ( global_status == ERROR );
|
|
} /* end is_in_error */
|
|
|
|
STATIC
|
|
int sci_get_comment_leader( char * rcs_file, char *leader )
|
|
{
|
|
char buf[MAXPATHLEN];
|
|
char *ptr;
|
|
char *lptr;
|
|
int found;
|
|
int status;
|
|
int i;
|
|
const char *av[16];
|
|
ERR_LOG log;
|
|
|
|
i = 0;
|
|
|
|
av[i++] = "rlog";
|
|
av[i++] = "-h";
|
|
av[i++] = rcs_file;
|
|
av[i] = NULL;
|
|
if ( ( log = oxm_runcmd ( rcs_monitor, i, av, NULL ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
found = FALSE;
|
|
while ( oxm_gets( rcs_monitor, buf, sizeof(buf), &log ) != NULL) {
|
|
if (strncmp(buf, "comment leader:", 15) == 0) {
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found) {
|
|
ui_print ( VFATAL, "Missing \"comment leader\" header in %s", rcs_file);
|
|
return( ERROR );
|
|
}
|
|
if ((ptr = strchr(buf, '\n')) == NULL) {
|
|
ui_print ( VFATAL, "Bad comment leader for %s", rcs_file);
|
|
|
|
return( ERROR );
|
|
}
|
|
*ptr-- = '\0';
|
|
if (*ptr != '"') {
|
|
ui_print ( VFATAL, "missing '\"' after comment for %s", rcs_file);
|
|
return( ERROR );
|
|
}
|
|
lptr = strchr(buf, *ptr);
|
|
if (lptr++ == ptr) {
|
|
ui_print ( VFATAL, "bad comment leader for %s", rcs_file);
|
|
return( ERROR );
|
|
}
|
|
memcpy(leader, lptr, ptr - lptr);
|
|
leader[ptr-lptr] = '\0';
|
|
if ( strcmp ( leader, "BIN" ) != 0 && strcmp ( leader, "NONE" ) != 0 &&
|
|
leader[strlen(leader)-1] != ' ' ) {
|
|
ui_print ( VWARN, "Comment leader must end with space.\n" );
|
|
ui_print ( VCONT, "File: %s.\n", rcs_file );
|
|
ui_print ( VCONT, "Comment leader: '%s'.\n", leader );
|
|
return ( ERROR );
|
|
} /* if */
|
|
ui_print ( VDEBUG, "In sci_get_comment_leader, leader is '%s'\n", leader );
|
|
log = oxm_endcmd( rcs_monitor, &status );
|
|
|
|
return( OK );
|
|
} /* end sci_get_comment_leader */
|
|
|
|
STATIC
|
|
void
|
|
src_ctl_setup_merge( void )
|
|
{
|
|
ui_print ( VDEBUG, "Entering src_ctl_setup_merge\n" );
|
|
(void) concat(temp1, sizeof(temp1), BCSTEMP, "/_BMERGE_1", NULL);
|
|
(void) concat(temp2, sizeof(temp2), BCSTEMP, "/_BMERGE_2", NULL);
|
|
(void) concat(temp3, sizeof(temp3), BCSTEMP, "/_BMERGE_3", NULL);
|
|
(void) concat(temp4, sizeof(temp4), BCSTEMP, "/_BMERGE_4", NULL);
|
|
(void) concat(temp5, sizeof(temp5), BCSTEMP, "/_BMERGE_5", NULL);
|
|
temp_merge_setup = TRUE;
|
|
ui_print ( VDEBUG, "Leaving src_ctl_setup_merge\n" );
|
|
} /* end src_ctl_setup_merge */
|
|
|
|
|
|
int
|
|
src_ctl_prep_merge( char *rev1, char *rev2, char *rev3,
|
|
SCI_ELEM sci_ptr)
|
|
/* expecting only an element, not an entire list */
|
|
{
|
|
int called_getancestor;
|
|
ERR_LOG log;
|
|
|
|
ui_print ( VDEBUG, "Entering src_ctl_prep_merge\n" );
|
|
|
|
/*
|
|
* determine revision number for "common" revision
|
|
*/
|
|
called_getancestor = FALSE;
|
|
log = (ERR_LOG) src_ctl_ancestor( sci_ptr -> name, sci_ptr -> ver_config,
|
|
rev1, rev2, &rev3, &called_getancestor,
|
|
sci_ptr -> ancestry );
|
|
sci_ptr -> called_getancestor = called_getancestor;
|
|
if ( log != OE_OK )
|
|
return( (int) log );
|
|
|
|
sci_ptr -> same23 = (strcmp(rev2, rev3) == 0);
|
|
sci_ptr -> same13 = (strcmp(rev1, rev3) == 0);
|
|
if ( sci_ptr -> same23) {
|
|
ui_print ( VALWAYS, "base revision %s\n", rev2);
|
|
ui_print ( VALWAYS, "common ancestor %s; will just use revision %s\n",
|
|
rev3, rev1);
|
|
ui_print ( VALWAYS, "No merge required\n", rev3 );
|
|
sci_ptr -> ver_ancestor = strdup ( rev3 );
|
|
if ( sci_ptr -> ver_ancestor == NULL ) {
|
|
ui_print ( VFATAL, "strdup failed\n" );
|
|
return ( ERROR );
|
|
}
|
|
return( OK );
|
|
}
|
|
if ( sci_ptr -> same13) {
|
|
sci_ptr -> ver_ancestor = strdup ( rev3 );
|
|
(void) unlink(temp1);
|
|
return( OK );
|
|
}
|
|
|
|
/*
|
|
* Test for binary file, if isn't allow merges.
|
|
*/
|
|
if ( sci_ptr -> leader == NULL || strcmp(sci_ptr -> leader, "BIN") != 0) {
|
|
sci_ptr -> need_merge = TRUE;
|
|
}
|
|
sci_ptr -> ver_ancestor = strdup ( rev3 );
|
|
if ( sci_ptr -> ver_ancestor == NULL ) {
|
|
ui_print ( VFATAL, "strdup failed\n" );
|
|
return ( ERROR );
|
|
}
|
|
ui_print ( VDEBUG, "Leaving src_ctl_prep_merge\n" );
|
|
return ( OK );
|
|
} /* src_ctl_prep_merge */
|
|
|
|
STATIC
|
|
int
|
|
src_ctl_config_lookup( SCI_ELEM sci_ptr, char * rev )
|
|
{
|
|
char buffer[MAXPATHLEN];
|
|
char cwbuf[MAXPATHLEN];
|
|
FILE *inf;
|
|
char *ptr, *p;
|
|
int len;
|
|
|
|
ui_print ( VDEBUG, "Entering src_ctl_config_lookup\n" );
|
|
ptr = concat(cwbuf, sizeof(cwbuf), sci_ptr -> name , ",v\t", NULL);
|
|
len = ptr - cwbuf;
|
|
if ((inf = fopen(bcsconfig, "r")) == NULL) {
|
|
ui_print ( VFATAL, "Can't open ancestor version file.\n" );
|
|
ui_print ( VCONT, "This file is created/updated as files are checked out.\n"
|
|
);
|
|
ui_print ( VCONT, "File: '%s'\n", bcsconfig );
|
|
return( ERROR );
|
|
} /* end if */
|
|
*rev = '\0';
|
|
while (fgets(buffer, sizeof(buffer), inf) != NULL) {
|
|
rm_newline ( buffer) ;
|
|
if (strncmp(buffer, cwbuf, len) != 0)
|
|
continue;
|
|
ptr = buffer + len;
|
|
while (*ptr == ' ' || *ptr == '\t')
|
|
ptr++;
|
|
if (*ptr < '0' || *ptr > '9') {
|
|
if (strcmp(ptr, "defunct") == 0) {
|
|
strcpy(rev, "defunct");
|
|
sci_ptr -> defunct = TRUE;
|
|
break;
|
|
}
|
|
ui_print ( VFATAL, "Invalid configuration line\n");
|
|
(void) fputs(buffer, stderr);
|
|
(void) fclose(inf);
|
|
return( ERROR );
|
|
} else if ( sci_ptr -> defunct) {
|
|
ui_print ( VFATAL, "Contradiction between .BCSconfig file and\n" );
|
|
ui_print ( VCONT, "information in source control system\n" );
|
|
ui_print ( VCONT, "regarding defunct status.\n" );
|
|
ui_print ( VCONT, "For file: '%s'\n", sci_ptr -> name );
|
|
return ( ERROR );
|
|
} /* end if */
|
|
for (p = rev; (*p = *ptr) != '\0'; p++, ptr++)
|
|
if (*p != '.' && (*p < '0' || *p > '9'))
|
|
break;
|
|
*p = '\0';
|
|
break;
|
|
}
|
|
if (ferror(inf) || fclose(inf) == EOF) {
|
|
ui_print ( VFATAL, "Error reading %s\n", bcsconfig);
|
|
return( ERROR );
|
|
} /* end if */
|
|
ui_print ( VDEBUG, "Leaving src_ctl_config_lookup\n" );
|
|
if ( *rev == '\0' ) {
|
|
ui_print ( VFATAL, "No information for file in .BCSconfig file.\n" );
|
|
ui_print ( VCONT, "File: '%s'\n", sci_ptr -> name );
|
|
return ( ERROR );
|
|
} else
|
|
return ( OK );
|
|
/* end if */
|
|
}
|
|
|
|
STATIC
|
|
const char *bmerge_action[] = {
|
|
"abort",
|
|
#define MA_ABORT 0
|
|
"ok",
|
|
#define MA_OK 1
|
|
"edit",
|
|
#define MA_EDIT 2
|
|
"merge",
|
|
#define MA_MERGE 3
|
|
"co",
|
|
#define MA_CO 4
|
|
"rco",
|
|
#define MA_RCO 5
|
|
"diff",
|
|
#define MA_DIFF 6
|
|
"rdiff",
|
|
#define MA_RDIFF 7
|
|
"leader",
|
|
#define MA_LEADER 8
|
|
"help",
|
|
#define MA_HELP 9
|
|
NULL
|
|
};
|
|
|
|
STATIC
|
|
const char *bci_action[] = {
|
|
"abort",
|
|
#define BA_ABORT 0
|
|
"diff",
|
|
#define BA_DIFF 1
|
|
"edit",
|
|
#define BA_EDIT 2
|
|
"check-in",
|
|
#define BA_CHECKIN 3
|
|
"leader",
|
|
#define BA_LEADER 4
|
|
"xtract",
|
|
#define BA_XTRACT 5
|
|
"log",
|
|
#define BA_LOG 6
|
|
"logdiff",
|
|
#define BA_LOGDIFF 7
|
|
"list",
|
|
#define BA_LIST 8
|
|
"auto",
|
|
#define BA_AUTO 9
|
|
"help",
|
|
#define BA_HELP 10
|
|
NULL
|
|
};
|
|
|
|
STATIC
|
|
int
|
|
src_ctl_merge ( SCI_ELEM sci_ptr )
|
|
{
|
|
int fd;
|
|
int status;
|
|
int pid;
|
|
ERR_LOG log;
|
|
HIST_ELEM merge_list;
|
|
HIST_ELEM user_list;
|
|
HIST_ELEM ancestor_list;
|
|
HIST_ELEM final_list;
|
|
|
|
ui_print ( VDEBUG, "Entering src_ctl_merge\n" );
|
|
if ( sci_ptr -> same23 || ! sci_ptr -> same13) {
|
|
(void) unlink(temp1);
|
|
if ((fd = open(temp1, O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write\n", temp1);
|
|
(void) unlink(temp1);
|
|
return( ERROR );
|
|
}
|
|
ui_print ( VDETAIL, "Retrieving revision %s\n", sci_ptr -> ver_merge );
|
|
status = src_ctl_check_out_with_fd( sci_ptr -> name, sci_ptr -> ver_merge,
|
|
fd, sci_ptr -> leader, &log);
|
|
(void) close(fd);
|
|
if (status != 0) {
|
|
ui_print ( VFATAL, "Check out failed.\n" );
|
|
(void) unlink(temp1);
|
|
return( ERROR );
|
|
}
|
|
if ( sci_ptr -> same23 ) {
|
|
if (rename(temp1, temp_working_file) < 0) {
|
|
ui_print ( VFATAL, "Unable to rename %s to %s\n", temp1, temp_working_file);
|
|
(void) unlink(temp1);
|
|
return( ERROR );
|
|
}
|
|
return( OK );
|
|
}
|
|
}
|
|
(void) unlink(temp2);
|
|
if ((fd = open(temp2, O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write", temp2);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
return( ERROR );
|
|
}
|
|
ui_print ( VDETAIL, "Retrieving revision %s\n", sci_ptr -> ver_user );
|
|
status = src_ctl_check_out_with_fd( sci_ptr -> name, sci_ptr -> ver_user, fd,
|
|
sci_ptr -> leader, &log);
|
|
(void) close(fd);
|
|
|
|
if (status != OK ) {
|
|
ui_print ( VFATAL, "Check out failed.\n", sci_ptr -> ver_user );
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
return( ERROR );
|
|
}
|
|
if ( sci_ptr -> same13) {
|
|
(void) unlink(temp1);
|
|
if (rename(temp2, temp_working_file) < 0) {
|
|
ui_print ( VFATAL, "Unable to rename %s to %s\n", temp2, temp_working_file);
|
|
(void) unlink(temp2);
|
|
return( ERROR );
|
|
}
|
|
return( OK );
|
|
}
|
|
if ( sci_ptr -> called_getancestor ) {
|
|
ui_print ( VALWAYS, "\n");
|
|
ui_print ( VALWAYS, "*** WARNING -- calculated common ancestor ***\n");
|
|
ui_print ( VALWAYS, "*** Check the merge differences carefully ***\n");
|
|
ui_print ( VALWAYS, "\n");
|
|
}
|
|
|
|
(void) unlink(temp3);
|
|
if ((fd = open(temp3, O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write\n", temp3);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
return( ERROR );
|
|
}
|
|
ui_print ( VDETAIL, "Retrieving common ancestor %s\n",
|
|
sci_ptr -> ver_ancestor );
|
|
status = src_ctl_check_out_with_fd( sci_ptr -> name, sci_ptr -> ver_ancestor,
|
|
fd, sci_ptr -> leader, &log);
|
|
(void) close(fd);
|
|
|
|
if ( status != OK ) {
|
|
ui_print ( VFATAL, "Failed to check out %s\n", sci_ptr -> ver_ancestor );
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
return( ERROR );
|
|
}
|
|
|
|
ui_print ( VDETAIL, "Merging differences between %s and %s to %s\n",
|
|
sci_ptr -> ver_merge, sci_ptr -> ver_user, temp_working_file);
|
|
(void) unlink(temp4);
|
|
if ((fd = open(temp4, O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write\n", temp4);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
return( ERROR );
|
|
}
|
|
merge_list = hst_xtract_file (temp1, sci_ptr->leader);
|
|
user_list = hst_xtract_file (temp2, sci_ptr->leader);
|
|
ancestor_list = hst_xtract_file (temp3, sci_ptr->leader);
|
|
pid = fd_runcmd("diff", BCSTEMP, TRUE, -1, fd,
|
|
"diff", temp1, temp3, NULL);
|
|
(void) close(fd);
|
|
if (pid == -1) {
|
|
ui_print ( VFATAL, "exec of diff failed.\n" );
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
return( ERROR );
|
|
}
|
|
status = endcmd(pid);
|
|
|
|
if (status != 0 && status != 1) {
|
|
ui_print ( VFATAL, "Diff command failed with status %d\n", status);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
return( ERROR );
|
|
}
|
|
(void) unlink(temp5);
|
|
if ((fd = open(temp5, O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write\n", temp5);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
return( ERROR );
|
|
}
|
|
pid = fd_runcmd("diff", BCSTEMP, TRUE, -1, fd,
|
|
"diff", temp2, temp3, NULL);
|
|
(void) close(fd);
|
|
if (pid == -1) {
|
|
ui_print ( VFATAL, "exec of diff failed.\n" );
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
return( ERROR );
|
|
}
|
|
status = endcmd(pid);
|
|
if (status != 0 && status != 1) {
|
|
ui_print ( VFATAL, "exec of diff failed.\n" );
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
return( ERROR );
|
|
}
|
|
|
|
|
|
|
|
|
|
fd = open(temp_working_file, O_WRONLY|O_TRUNC|O_CREAT, 0600);
|
|
if (fd < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write\n", temp_working_file);
|
|
(void) unlink(temp_working_file);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
return( ERROR );
|
|
}
|
|
pid = fd_runcmd("rcsdiff3", BCSTEMP, TRUE, -1, fd,
|
|
"rcsdiff3", "-r", temp4, temp5, temp1, temp2, temp3,
|
|
sci_ptr -> ver_merge, sci_ptr -> ver_user, NULL);
|
|
if (pid == -1) {
|
|
ui_print ( VFATAL, "exec of rcsdiff3 failed.\n" );
|
|
(void) close(fd);
|
|
(void) unlink(temp_working_file);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
return( ERROR );
|
|
}
|
|
(void) close(fd);
|
|
status = endcmd(pid);
|
|
if (status == -1) {
|
|
ui_print ( VFATAL, "rcsdiff3 failed\n");
|
|
(void) unlink(temp_working_file);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
return( ERROR );
|
|
}
|
|
if (status == 255) {
|
|
ui_print ( VWARN, "Merge failed\n");
|
|
(void) unlink(temp_working_file);
|
|
} else if (status != 0)
|
|
ui_print ( VALWAYS, "Warning: %d overlaps during merge.\n", status);
|
|
if (status == 0)
|
|
ui_print ( VALWAYS, "Merge successful.\n");
|
|
|
|
final_list = hst_merge_lists (merge_list, user_list, ancestor_list);
|
|
|
|
hst_insert_file (temp_working_file, final_list, sci_ptr -> leader);
|
|
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
(void) unlink(temp3);
|
|
(void) unlink(temp4);
|
|
(void) unlink(temp5);
|
|
|
|
ui_print ( VDEBUG, "Leaving src_ctl_merge\n" );
|
|
return(status ? ERROR : 1);
|
|
} /* end src_ctl_merge */
|
|
|
|
STATIC
|
|
void
|
|
get_str( char *prompt, char *deflt, char *buf)
|
|
{
|
|
(void) getstr(prompt, deflt, buf);
|
|
} /* get_str */
|
|
|
|
/*
|
|
* FIXME
|
|
* Temporary. This makes sure that the rcs_monitor connection
|
|
* is closed during user input. This won't be necessary if the odexm
|
|
* supports time-outs.
|
|
*/
|
|
BOOLEAN cnxtn_open = FALSE;
|
|
|
|
STATIC
|
|
int get_bmerge_action( SCI_ELEM sci_ptr, int initial_key, BOOLEAN no_log )
|
|
{
|
|
const char *def = NULL;
|
|
int key;
|
|
struct stat st;
|
|
int status;
|
|
BOOLEAN improper = FALSE;
|
|
char leader [ MAXPATHLEN ];
|
|
char prompt[MAXPATHLEN];
|
|
char deflt[MAXPATHLEN];
|
|
ERR_LOG log;
|
|
|
|
key = initial_key;
|
|
for (;;) {
|
|
switch (key) {
|
|
case MA_ABORT:
|
|
(void) unlink(temp_working_file);
|
|
return ( ABORT );
|
|
case MA_OK:
|
|
if (stat(temp_working_file, &st) < 0) {
|
|
def = "merge";
|
|
break;
|
|
}
|
|
if ( sci_has_log ( sci_ptr ) )
|
|
if ( ( log = checklogstate ( temp_working_file, sci_ptr -> leader,
|
|
&improper )) != OE_OK) {
|
|
ui_print ( VWARN,
|
|
"Improper markers or history section in file %s\n",
|
|
sci_ptr->name);
|
|
return ( ERROR );
|
|
} else if ( improper ) {
|
|
def = "edit";
|
|
break;
|
|
} /* if */
|
|
/* if */
|
|
return ( OK );
|
|
case MA_EDIT:
|
|
if (stat(temp_working_file, &st) < 0) {
|
|
break;
|
|
}
|
|
ui_print ( VDEBUG, "%s %s\n", EDIT_PROG, temp_working_file );
|
|
if ( cnxtn_open ) {
|
|
log = oxm_close ( rcs_monitor );
|
|
cnxtn_open = FALSE;
|
|
} /* if */
|
|
(void) runp(EDIT_PROG, EDIT_PROG, temp_working_file, NULL);
|
|
def = "rdiff";
|
|
break;
|
|
case MA_MERGE:
|
|
(void) unlink(temp_working_file);
|
|
if ( !cnxtn_open ) {
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
cnxtn_open = TRUE;
|
|
} /* if */
|
|
status = src_ctl_merge( sci_ptr );
|
|
if (status == 0) {
|
|
def = "ok";
|
|
break;
|
|
}
|
|
if (stat(temp_working_file, &st) < 0)
|
|
def = "merge";
|
|
else if (status == 1)
|
|
def = "rdiff";
|
|
else
|
|
def = "edit";
|
|
break;
|
|
case MA_RCO:
|
|
(void) unlink(temp_working_file);
|
|
if ( !cnxtn_open ) {
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
cnxtn_open = TRUE;
|
|
} /* if */
|
|
if ( src_ctl_check_out( sci_ptr -> name, sci_ptr -> ver_user,
|
|
sci_ptr -> leader, &log )
|
|
== 0) {
|
|
if (stat(temp_working_file, &st) < 0) {
|
|
ui_print ( VFATAL, "stat %s", temp_working_file);
|
|
return ( ERROR );
|
|
} else if (chmod(temp_working_file,
|
|
(int)(st.st_mode|S_IWRITE)&0777) < 0) {
|
|
ui_print ( VFATAL, "chmod %s", temp_working_file);
|
|
return ( ERROR );
|
|
}
|
|
def = "diff";
|
|
}
|
|
break;
|
|
case MA_CO:
|
|
(void) unlink(temp_working_file);
|
|
if ( !cnxtn_open ) {
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
cnxtn_open = TRUE;
|
|
} /* if */
|
|
if ( src_ctl_check_out( sci_ptr -> name, sci_ptr -> ver_merge,
|
|
sci_ptr -> leader, &log )
|
|
== 0) {
|
|
|
|
if (stat(temp_working_file, &st) < 0) {
|
|
ui_print ( VFATAL, "stat %s", temp_working_file);
|
|
return ( ERROR );
|
|
} else if (chmod(temp_working_file,
|
|
(int)(st.st_mode|S_IWRITE)&0777) < 0) {
|
|
ui_print ( VFATAL, "chmod %s", temp_working_file);
|
|
}
|
|
def = "ok";
|
|
}
|
|
break;
|
|
case MA_RDIFF:
|
|
if (stat(temp_working_file, &st) < 0) {
|
|
def = "merge";
|
|
break;
|
|
}
|
|
if ( !cnxtn_open ) {
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
cnxtn_open = TRUE;
|
|
} /* if */
|
|
if (src_ctl_diff_rev_with_file( sci_ptr -> ver_user,
|
|
temp_working_file, sci_ptr -> name,
|
|
-1, FALSE, FALSE, &log) != 0) {
|
|
break;
|
|
}
|
|
def = "diff";
|
|
break;
|
|
case MA_DIFF:
|
|
if (stat(temp_working_file, &st) < 0) {
|
|
def = "merge";
|
|
break;
|
|
}
|
|
if ( !cnxtn_open ) {
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
cnxtn_open = TRUE;
|
|
} /* if */
|
|
if (src_ctl_diff_rev_with_file( sci_ptr -> ver_merge,
|
|
temp_working_file, sci_ptr -> name,
|
|
-1, FALSE, FALSE, &log) != 0) {
|
|
break;
|
|
}
|
|
def = "ok";
|
|
break;
|
|
case MA_LEADER:
|
|
strcpy ( leader, sci_ptr -> leader );
|
|
(void) concat(prompt, sizeof(prompt),
|
|
"Comment leader for ", sci_ptr -> name, NULL);
|
|
(void) strcpy(deflt, ( *leader == NUL) ? "NONE" : leader);
|
|
for (;;) {
|
|
get_str(prompt, deflt, leader);
|
|
if (strcmp(leader, deflt) == 0)
|
|
break;
|
|
(void) strcpy(deflt, leader);
|
|
}
|
|
if ( !cnxtn_open ) {
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
cnxtn_open = TRUE;
|
|
} /* if */
|
|
sci_set_comment_leader ( sci_ptr, leader );
|
|
break;
|
|
case MA_HELP:
|
|
ui_print ( VALWAYS, "One of the following:\n\n");
|
|
ui_print ( VALWAYS, " abort - abort merge for %s\n", canon_working_file);
|
|
ui_print ( VALWAYS, " ok - done with merged %s; do next file\n",
|
|
canon_working_file);
|
|
ui_print ( VALWAYS, " edit - edit merged %s\n", canon_working_file);
|
|
ui_print ( VALWAYS, " merge - merge source version of set '%s' into %s\n",
|
|
BCSSET_NAME, canon_working_file);
|
|
ui_print ( VALWAYS, " co - check-out %s from submit build without merging\n",
|
|
canon_working_file);
|
|
ui_print ( VALWAYS, " rco - check-out %s from user's private branch without merging\n",
|
|
canon_working_file);
|
|
ui_print ( VALWAYS, " diff - compare merged %s with submit build\n",
|
|
canon_working_file);
|
|
ui_print ( VALWAYS, " rdiff - compare merged %s with user's private branch\n",
|
|
canon_working_file);
|
|
ui_print ( VALWAYS, " leader - set the comment leader\n" );
|
|
ui_print ( VALWAYS, "\n");
|
|
|
|
}
|
|
/*
|
|
* This is rather messy, but it works.
|
|
* Test if file is binary, if it isn't, allow the merge.
|
|
* If no real merge is required, key is set to MA_OK
|
|
* and the MA_OK action is taken.
|
|
*/
|
|
if ( (sci_ptr -> need_merge || improper) && (strcmp(sci_ptr -> leader, "BIN") != 0) ) {
|
|
if ( cnxtn_open ) {
|
|
log = oxm_close ( rcs_monitor );
|
|
cnxtn_open = FALSE;
|
|
} /* if */
|
|
key = getstab("Abort, ok, edit, merge, rco, co,\nrdiff, diff, leader",
|
|
bmerge_action, def);
|
|
} else
|
|
key = MA_OK;
|
|
} /* for */
|
|
} /* end get_bmerge_action */
|
|
|
|
|
|
STATIC
|
|
int
|
|
merge_elem ( SCI_ELEM sci_ptr, BOOLEAN no_log )
|
|
{
|
|
int status = OK;
|
|
int bmerge_status;
|
|
|
|
ui_print ( VDEBUG, "Entering merge_elem\n" );
|
|
check_path ( sci_ptr -> name );
|
|
bmerge_status = get_bmerge_action ( sci_ptr, MA_MERGE, no_log );
|
|
if ( bmerge_status != OK )
|
|
status = bmerge_status;
|
|
/* end if */
|
|
ui_print ( VDEBUG, "Leaving merge_elem\n" );
|
|
return ( status );
|
|
} /* end merge_elem */
|
|
|
|
STATIC
|
|
int
|
|
setup_bcstemp( void )
|
|
{
|
|
struct stat st;
|
|
int changes = FALSE;
|
|
|
|
if (stat(BCSTEMP, &st) < 0 || (st.st_mode&S_IFMT) != S_IFDIR) {
|
|
ui_print ( VDETAIL, "Creating %s\n", BCSTEMP);
|
|
(void) unlink(BCSTEMP);
|
|
if (makedir(BCSTEMP) != 0) {
|
|
ui_print ( VFATAL, "Unable to create %s directory\n", BCSTEMP);
|
|
return ( ERROR );
|
|
} /* end if */
|
|
if (stat(BCSTEMP, &st) < 0) {
|
|
ui_print ( VFATAL, "Unable to stat %s directory\n", BCSTEMP);
|
|
return ( ERROR );
|
|
} /* end if */
|
|
changes = TRUE;
|
|
}
|
|
if (changes) {
|
|
if ( ui_ver_level() >= VDETAIL ) {
|
|
ui_print ( VDEBUG, "ls -lgd %s\n", BCSTEMP );
|
|
(void) runp("ls", "ls", "-lgd", BCSTEMP, NULL);
|
|
} /* end if */
|
|
} /* end if */
|
|
return ( OK );
|
|
} /* end setup_bcstemp */
|
|
|
|
|
|
STATIC
|
|
int
|
|
src_ctl_set_remove( SCI_ELEM sci_ptr )
|
|
{
|
|
char buf[MAXPATHLEN];
|
|
char buffer[MAXPATHLEN];
|
|
char cwbuf[MAXPATHLEN];
|
|
FILE *inf, *outf;
|
|
int wcnt;
|
|
|
|
ui_print ( VDEBUG, "[ updating ./.BCSset-%s ]\n", BCSSET_NAME);
|
|
(void) concat(buf, sizeof(buf), bcsset, ".tmp", NULL);
|
|
(void) unlink(buf);
|
|
if ((outf = fopen(buf, "w")) == NULL) {
|
|
ui_print ( VFATAL, "Unable to open %s for write\n", buf);
|
|
return( ERROR );
|
|
}
|
|
(void) concat(cwbuf, sizeof(cwbuf), sci_ptr -> name, "\n", NULL);
|
|
wcnt = 0;
|
|
if ((inf = fopen(bcsset, "r")) != NULL) {
|
|
while (fgets(buffer, sizeof(buffer), inf) != NULL) {
|
|
if (strcmp(buffer, cwbuf) == 0) {
|
|
if ( ui_ver_level () >= VQUIET )
|
|
fprintf(stderr, "< %s", cwbuf);
|
|
continue;
|
|
}
|
|
(void) fputs(buffer, outf);
|
|
wcnt++;
|
|
}
|
|
if (ferror(inf) || fclose(inf) == EOF) {
|
|
ui_print ( VFATAL, "Error reading %s\n", bcsset);
|
|
(void) fclose(outf);
|
|
(void) unlink(buf);
|
|
return( ERROR );
|
|
}
|
|
}
|
|
if (ferror(outf) || fclose(outf) == EOF) {
|
|
ui_print ( VFATAL, "Error writing %s\n", buf);
|
|
(void) unlink(buf);
|
|
return( ERROR );
|
|
}
|
|
if (rename(buf, bcsset) < 0) {
|
|
ui_print ( VFATAL, "4 Rename %s to %s failed\n", buf, bcsset);
|
|
return ( ERROR );
|
|
}
|
|
if (wcnt == 0)
|
|
set_cleanup();
|
|
return( OK );
|
|
}
|
|
|
|
STATIC
|
|
void set_cleanup( void )
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(bcsset, &st) == 0 && st.st_size > 0)
|
|
return;
|
|
if (unlink(bcsset) == 0 )
|
|
ui_print ( VDETAIL, "rm: removing ./.BCSset-%s\n", BCSSET_NAME);
|
|
if (unlink(bcslog) == 0 )
|
|
ui_print ( VDETAIL, "rm: removing ./.BCSlog-%s\n", BCSSET_NAME);
|
|
if (unlink(bcspath) == 0 )
|
|
ui_print ( VDETAIL, "rm: removing ./.BCSpath-%s\n", BCSSET_NAME);
|
|
}
|
|
|
|
/*
|
|
* END OF SUPPORTING FUNCTIONS
|
|
*/
|
|
|
|
char * check_out_config;
|
|
/*
|
|
* FUNCTION set_source_info
|
|
*/
|
|
int
|
|
set_source_info ( struct rcfile * contents, char * usr_rcfile,
|
|
char * sb_base, char * sb, char ** def_set )
|
|
{
|
|
char * rcs_relay;
|
|
char * src_relay;
|
|
char * logs_relay;
|
|
char * submit_host;
|
|
char buf [MAXPATHLEN];
|
|
char buf2 [MAXPATHLEN];
|
|
char * project_name;
|
|
char * def_build;
|
|
char * project;
|
|
char * sub_project;
|
|
struct rcfile sb_contents;
|
|
char * backing_project;
|
|
char * backing_build;
|
|
BOOLEAN ode_sc;
|
|
BOOLEAN ode_build_env;
|
|
char * tcp_service_number = NULL;
|
|
char copyright_file [MAXPATHLEN];
|
|
char * check_copyrights;
|
|
|
|
/*
|
|
if (parse_rc_file(sb_rcfile, &rcfile) != 0) {
|
|
*/
|
|
prj_read ( sb_full_path ( sb_base, sb ), org_path, &project, &sub_project );
|
|
sb_conf_read ( &sb_contents, sb_full_path ( sb_base, sb ), project,
|
|
sub_project );
|
|
sb_conf_std ( &sb_contents, &backing_project, &backing_build, &ode_sc,
|
|
&ode_build_env );
|
|
if ( backing_build == NULL ) {
|
|
if ( submitting ) {
|
|
ui_print ( VWARN, "This build is not backed.\n" );
|
|
ui_print ( VCONT, "You cannot submit files from here.\n" );
|
|
return ( ERROR );
|
|
} /* if */
|
|
backing_build = sb_full_path ( sb_base, sb );
|
|
} /* if */
|
|
if ( sub_project == NULL ) {
|
|
concat ( buf2, sizeof (buf2), backing_build, "/rc_files/", project, NULL );
|
|
} else {
|
|
concat ( buf2, sizeof (buf2), backing_build, "/rc_files/", project, NULL );
|
|
} /* if */
|
|
concat ( buf, sizeof (buf), buf2, "/sc.conf", NULL );
|
|
if ( init_rc_contents ( contents, buf ) == ERROR ) {
|
|
ui_print ( VFATAL, "Unable to parse sandbox");
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* end if */
|
|
if ( get_rc_value ( "check_copyrights", &check_copyrights, contents, FALSE )
|
|
== OK ) {
|
|
if ( strcmp ( check_copyrights, "true" ) == 0 ) {
|
|
concat ( copyright_file, sizeof(copyright_file), buf2, "/copyrights",
|
|
NULL );
|
|
if ( ( ERR_LOG ) read_legal_copyrights2 ( copyright_file ) != OE_OK ) {
|
|
return ( ERROR );
|
|
} /* if */
|
|
} /* if */
|
|
} /* if */
|
|
get_rc_value ( "rcs_host", &rcfile_rcs_host, contents, TRUE );
|
|
get_rc_value ( "source_host", &rcfile_source_host, contents, TRUE );
|
|
|
|
if ( get_rc_value ( "rcs_relay", &rcs_relay, contents, TRUE ) != OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
#ifdef notdef
|
|
if ((stat( rcs_relay, &st_buf) < 0))
|
|
{
|
|
ui_print ( VFATAL, "Unable to access relay program (%s).\n", rcs_relay);
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* if */
|
|
#endif
|
|
if ( get_rc_value ( "src_relay", &src_relay, contents, TRUE ) != OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
#ifdef notdef
|
|
if ((stat( src_relay, &st_buf) < 0))
|
|
{
|
|
ui_print ( VFATAL, "Unable to access relay program (%s).\n", src_relay);
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* if */
|
|
#endif
|
|
if ( get_rc_value ( "logs_relay", &logs_relay, contents, TRUE ) != OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
#ifdef notdef
|
|
if ((stat( logs_relay, &st_buf) < 0))
|
|
{
|
|
ui_print ( VFATAL, "Unable to access relay program (%s).\n", logs_relay);
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* if */
|
|
#endif
|
|
get_rc_value ( "submit_host", &submit_host, contents, TRUE );
|
|
get_rc_value ( "default_build", &def_build, contents, TRUE );
|
|
get_rc_value ( "project_name", &project_name, contents, TRUE );
|
|
get_rc_value ( "check_out_config", &check_out_config, contents, TRUE );
|
|
get_rc_value ( "default_set", def_set, contents, TRUE );
|
|
get_rc_value ( "tcp_service_number", &tcp_service_number, contents, FALSE );
|
|
oxminit [RCS_MONITOR].monitor = RCS_MONITOR;
|
|
oxminit [RCS_MONITOR].host = strdup ( rcfile_rcs_host );
|
|
oxminit [RCS_MONITOR].relay = strdup ( rcs_relay );
|
|
if ( sub_project == NULL ) {
|
|
concat ( buf, sizeof ( buf ), "rcs/", project_name, "/", def_build, NULL );
|
|
} else {
|
|
concat ( buf, sizeof ( buf ), "rcs/", project_name, "/", sub_project, "/",
|
|
def_build, NULL );
|
|
} /* if */
|
|
oxminit [RCS_MONITOR].ident = strdup ( buf );
|
|
oxminit [RCS_MONITOR].port = tcp_service_number;
|
|
oxminit [SRC_MONITOR].monitor = SRC_MONITOR;
|
|
oxminit [SRC_MONITOR].host = strdup ( rcfile_source_host );
|
|
oxminit [SRC_MONITOR].relay = strdup ( src_relay );
|
|
concat ( buf, sizeof ( buf ), "src/", project_name, "/", def_build, NULL );
|
|
oxminit [SRC_MONITOR].ident = strdup ( buf );
|
|
oxminit [SRC_MONITOR].port = tcp_service_number;
|
|
oxminit [LOGS_MONITOR].monitor = LOGS_MONITOR;
|
|
oxminit [LOGS_MONITOR].host = strdup ( submit_host );
|
|
oxminit [LOGS_MONITOR].relay = strdup ( logs_relay );
|
|
concat ( buf, sizeof ( buf ), "logs/", project_name, "/", def_build, NULL );
|
|
oxminit [LOGS_MONITOR].ident = strdup ( buf );
|
|
oxminit [LOGS_MONITOR].port = tcp_service_number;
|
|
return ( OK );
|
|
} /* end set_source_info */
|
|
|
|
int getenv_user ( char ** user )
|
|
|
|
/* This procedure gets the user's name. */
|
|
|
|
{
|
|
char * env_ptr; /* point to env string */
|
|
|
|
if (( env_ptr = getenv ( "USER" )) == NULL ) { /* insert user name */
|
|
ui_print ( VFATAL, "USER not found in environment.\n" );
|
|
return (ERROR );
|
|
}
|
|
|
|
*user = strdup ( env_ptr );
|
|
return ( OK );
|
|
}
|
|
|
|
void
|
|
get_full_setname ( char * setn, char * user, char ** symbolic_name )
|
|
|
|
/* This procedure prepends the user name to the setname
|
|
if the setname does not start with a capital letter
|
|
and it isn't already there. It puts the final setname
|
|
in setinfo. */
|
|
|
|
{
|
|
char tmp_name [ NAME_LEN ], /* misc string */
|
|
tmp_name2 [ NAME_LEN ], /* misc string */
|
|
* ptr; /* point to env string */
|
|
|
|
if (( ptr = concat ( tmp_name, NAME_LEN , user, "_", NULL ))
|
|
== NULL)
|
|
uquit ( ERROR, FALSE, "\tno room in buffer for '%s_'\n", user );
|
|
|
|
if ((( *setn < 'A' ) || ( *setn > 'Z' )) &&
|
|
( strncmp ( tmp_name, setn, ptr - tmp_name ))) {
|
|
concat ( tmp_name2, NAME_LEN, tmp_name, setn, NULL );
|
|
*symbolic_name = strdup ( tmp_name2 );
|
|
} else {
|
|
*symbolic_name = strdup ( setn );
|
|
} /* if */
|
|
}
|
|
|
|
int
|
|
sci_init3 ( const char * submit_set, struct rcfile * contents )
|
|
{
|
|
char config_file[MAXPATHLEN];
|
|
|
|
concat(config_file, sizeof(config_file), "ode2.3_server_base/sets/",
|
|
submit_set, "/sc.conf", NULL );
|
|
if ( init_rc_contents ( contents, config_file ) == ERROR ) {
|
|
ui_print ( VFATAL, "Unable to parse sandbox");
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* end if */
|
|
return ( OK );
|
|
} /* end sci_init3 */
|
|
|
|
int
|
|
sci_init2 ( char * submit_set )
|
|
{
|
|
char * src_relay;
|
|
char * logs_relay;
|
|
char * submit_host;
|
|
char buf [MAXPATHLEN];
|
|
char * project_name;
|
|
char * def_build;
|
|
char * def_set;
|
|
struct rcfile contents;
|
|
ERR_LOG log;
|
|
char * tcp_service_number = NULL;
|
|
|
|
BCSTEMP = strdup ( "/tmp" );
|
|
sci_init3 ( submit_set, &contents );
|
|
log = (ERR_LOG) read_legal_copyrights ( &contents );
|
|
get_rc_value ( "rcs_host", &rcfile_rcs_host, &contents, TRUE );
|
|
get_rc_value ( "source_host", &rcfile_source_host, &contents, TRUE );
|
|
|
|
if ( get_rc_value ( "src_relay", &src_relay, &contents, TRUE ) != OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
#ifdef notdef
|
|
if ((stat( src_relay, &st_buf) < 0))
|
|
{
|
|
ui_print ( VFATAL, "Unable to access relay program (%s).\n", src_relay);
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* if */
|
|
#endif
|
|
if ( get_rc_value ( "logs_relay", &logs_relay, &contents, TRUE ) != OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
#ifdef notdef
|
|
if ((stat( logs_relay, &st_buf) < 0))
|
|
{
|
|
ui_print ( VFATAL, "Unable to access relay program (%s).\n", logs_relay);
|
|
return ( ERROR ); /* unable to continue */
|
|
} /* if */
|
|
#endif
|
|
get_rc_value ( "submit_host", &submit_host, &contents, TRUE );
|
|
get_rc_value ( "default_build", &def_build, &contents, TRUE );
|
|
get_rc_value ( "project_name", &project_name, &contents, TRUE );
|
|
get_rc_value ( "check_out_config", &check_out_config, &contents, TRUE );
|
|
get_rc_value ( "default_set", &def_set, &contents, TRUE );
|
|
get_rc_value ( "tcp_service_number", &tcp_service_number, &contents, FALSE );
|
|
oxminit [SRC_MONITOR].monitor = SRC_MONITOR;
|
|
oxminit [SRC_MONITOR].host = strdup ( rcfile_source_host );
|
|
oxminit [SRC_MONITOR].relay = strdup ( src_relay );
|
|
concat ( buf, sizeof ( buf ), "src/", project_name, "/", def_build, NULL );
|
|
oxminit [SRC_MONITOR].ident = strdup ( buf );
|
|
oxminit [SRC_MONITOR].port = tcp_service_number;
|
|
oxminit [LOGS_MONITOR].monitor = LOGS_MONITOR;
|
|
oxminit [LOGS_MONITOR].host = strdup ( submit_host );
|
|
oxminit [LOGS_MONITOR].relay = strdup ( logs_relay );
|
|
concat ( buf, sizeof ( buf ), "logs/", project_name, "/", def_build, NULL );
|
|
oxminit [LOGS_MONITOR].ident = strdup ( buf );
|
|
oxminit [LOGS_MONITOR].port = tcp_service_number;
|
|
oxm_init ( MAX_MONITORS, oxminit );
|
|
return ( OK );
|
|
} /* end sci_init2 */
|
|
|
|
/*
|
|
* FUNCTION sci_init
|
|
*
|
|
* This function needs to be called at the beginning of
|
|
* a source control sesion, before any other sci_* calls are
|
|
* made, to get setup information such as which server to use, etc.
|
|
*/
|
|
int
|
|
sci_init (
|
|
struct rcfile * contents,
|
|
char ** sb,
|
|
char ** sb_base,
|
|
char ** set,
|
|
char ** submit_set,
|
|
char ** sbrc_file,
|
|
int f,
|
|
BOOLEAN s )
|
|
{
|
|
char buf[MAXPATHLEN];
|
|
int status;
|
|
char * symbolic_name = NULL;
|
|
char * setdir = NULL;
|
|
char def_build_rc_file [ MAXPATHLEN ];
|
|
ERR_LOG log;
|
|
char * rc_file = NULL;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_init\n" );
|
|
file_mode = f;
|
|
submitting = s;
|
|
getenv_user ( &USER );
|
|
if ( *set != NULL ) {
|
|
get_full_setname ( *set, USER, &symbolic_name );
|
|
} /* if */
|
|
if ( current_sb ( sb, sb_base, sbrc_file, &rc_file ) == ERROR ) {
|
|
ui_print ( VFATAL, "Could not establish sandbox environment.\n" );
|
|
exit ( ERROR );
|
|
} /* if */
|
|
if ( current_set ( &symbolic_name, &setdir, sb, &rc_file ) == ERROR ) {
|
|
if ( symbolic_name == NULL )
|
|
uquit ( ERROR, FALSE, "\tsb, %s, has no default set.\n", *sb );
|
|
else
|
|
uquit ( ERROR, FALSE, "\tthe set, %s, is not part of the sandbox, %s.\n",
|
|
symbolic_name, *sb );
|
|
} /* if */
|
|
#ifdef notdef
|
|
if ( default_build ( &build_dir, &def_build, &def_set, *sbrc_file )
|
|
== ERROR ) {
|
|
ui_print ( VFATAL, "Could not find project directory or default build.\n" );
|
|
return ( ERROR );
|
|
} /* if */
|
|
concat ( def_build_rc_file, sizeof ( def_build_rc_file ), build_dir, "/",
|
|
def_build, "/", SANDBOXRC, NULL );
|
|
#endif
|
|
if (get_src_and_org_paths ( *sb_base, *sb ) == ERROR)
|
|
exit ( ERROR );
|
|
|
|
if ( set_source_info ( contents, def_build_rc_file, *sb_base, *sb,
|
|
submit_set ) != OK ) {
|
|
return ( ERROR );
|
|
} /* if */
|
|
|
|
*set = symbolic_name;
|
|
|
|
oxm_init ( MAX_MONITORS, oxminit );
|
|
|
|
atomic_init ();
|
|
|
|
status = OK;
|
|
if (getuid() != geteuid() || getgid() != getegid()) {
|
|
ui_print ( VFATAL, "Branch rcs commands should not run setuid\n" );
|
|
status = ERROR;
|
|
} /* if */
|
|
if ((EDIT_PROG = getenv(EDITOR)) == NULL)
|
|
EDIT_PROG = DEF_EDITOR;
|
|
/* if */
|
|
|
|
/*
|
|
* BCSTEMP - temporary directory for bcs commands
|
|
*/
|
|
(void) concat(bcstempbuf, sizeof(bcstempbuf),
|
|
*sb_base, "/", *sb, "/tmp", NULL);
|
|
BCSTEMP = bcstempbuf;
|
|
status = setup_bcstemp ( );
|
|
if ( status != OK )
|
|
return ( status );
|
|
/* end if */
|
|
|
|
(void) concat(mesgfile, sizeof(mesgfile), BCSTEMP, "/_LOG_", NULL);
|
|
|
|
/*
|
|
* BCSSET_NAME - set name to use for bcs commands
|
|
*/
|
|
BCSSET_NAME = *set;
|
|
if (strcmp(BCSSET_NAME, "TRUNK") == 0) {
|
|
usetrunk = TRUE;
|
|
(void) strcpy(setrev, "-r");
|
|
} else {
|
|
if (BCSSET_NAME[0] >= '0' && BCSSET_NAME[0] <= '9') {
|
|
usetrunk = TRUE;
|
|
} else {
|
|
usetrunk = FALSE;
|
|
if (strncmp(BCSSET_NAME, USER, strlen(USER)) != 0 &&
|
|
(BCSSET_NAME[0] < 'A' || BCSSET_NAME[0] > 'Z')) {
|
|
(void) concat(setrev, sizeof(setrev),
|
|
USER, "_", BCSSET_NAME, NULL);
|
|
(void) strcpy(buf, setrev);
|
|
BCSSET_NAME = buf;
|
|
}
|
|
}
|
|
(void) concat(setrev, sizeof(setrev), "-r", BCSSET_NAME, NULL);
|
|
}
|
|
if (setenv(BCSSET, BCSSET_NAME, TRUE) < 0) {
|
|
ui_print ( VFATAL, "BCSSET setenv failed");
|
|
return ( ERROR );
|
|
}
|
|
BCSSET_NAME = getenv(BCSSET);
|
|
if (BCSSET_NAME == NULL) {
|
|
ui_print ( VFATAL, "BCSSET not defined");
|
|
return ( ERROR );
|
|
}
|
|
|
|
/*
|
|
* generate set dependent information
|
|
*/
|
|
(void) concat(bcsconfig, sizeof(bcsconfig),
|
|
src_path, "/.BCSconfig", NULL);
|
|
(void) concat(bcsset, sizeof(bcsset),
|
|
src_path, "/.BCSset-", BCSSET_NAME, NULL);
|
|
(void) concat(bcslog, sizeof(bcslog),
|
|
src_path, "/.BCSlog-", BCSSET_NAME, NULL);
|
|
(void) concat(bcspath, sizeof(bcspath),
|
|
src_path, "/.BCSpath-", BCSSET_NAME, NULL);
|
|
|
|
if ( chdir ( src_path ) < 0 ) {
|
|
ui_print ( VFATAL, "Could not cd to source path: '%s'\n", src_path );
|
|
return ( ERROR );
|
|
} /* if */
|
|
|
|
if ( (log = (ERR_LOG) read_legal_copyrights ( contents ) ) != OE_OK ) {
|
|
ui_print ( VFATAL, "%s\n", err_str ( log ) );
|
|
status = ERROR;
|
|
} /* if */
|
|
get_rc_value ("copyright_years", ©right_years, contents, FALSE);
|
|
ui_print ( VDEBUG, "Leaving sci_init\n" );
|
|
return ( status );
|
|
} /* end sci_init */
|
|
|
|
|
|
/*
|
|
* The following variables are utilized by sci_new_list and confirm_alloc.
|
|
*/
|
|
|
|
#define MAX_SCI_LIST 100
|
|
|
|
STATIC
|
|
int serial_num = 0;
|
|
|
|
STATIC
|
|
SCI_LIST serial_list [ MAX_SCI_LIST ];
|
|
|
|
/*
|
|
* FUNCTION confirm_alloc
|
|
*
|
|
* Confirm that the given object was actually allocated.
|
|
*/
|
|
BOOLEAN
|
|
confirm_alloc ( SCI_LIST sl )
|
|
{
|
|
if ( sl != NULL && sl -> serial_num >= 0 &&
|
|
sl -> serial_num <= ( MAX_SCI_LIST - 1) &&
|
|
serial_list [ sl -> serial_num ] == sl )
|
|
return ( TRUE );
|
|
else {
|
|
ui_print ( VALWAYS, "\n*** INTERNAL ERROR 0001 ***\n\n" );
|
|
ui_print ( VFATAL, "Unallocated object detected.\n" );
|
|
ui_print ( VCONT, "Report failure immediately!!\n" );
|
|
report_current_function ( );
|
|
ui_print ( VALWAYS, "\n" );
|
|
log_error ( );
|
|
return ( FALSE );
|
|
} /* end if */
|
|
} /* end confirm_alloc */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_new_list
|
|
*
|
|
* Create a new list. Must be called before any calls to sci_add_to_list
|
|
* are made.
|
|
*/
|
|
int
|
|
sci_new_list ( SCI_LIST * sl )
|
|
{
|
|
BOOLEAN status;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_new_list\n" );
|
|
*sl = ( SCI_LIST ) malloc ( (size_t) sizeof ( struct sci_list ) );
|
|
if ( *sl == NULL) {
|
|
ui_print ( VFATAL, "Unable to allocate %d bytes of memory!\n" );
|
|
ui_print ( VFATAL, "Function: sci_new_list.\n" );
|
|
status = ERROR;
|
|
} else {
|
|
if ( serial_num == MAX_SCI_LIST ) {
|
|
ui_print ( VFATAL, "Exceeded limit set on number of\n" );
|
|
ui_print ( VCONT, "SCI_LIST objects that may be allocated.\n" );
|
|
ui_print ( VCONT, "Limit currently set at: %d.\n", MAX_SCI_LIST );
|
|
status = ERROR;
|
|
} else {
|
|
serial_list [ serial_num ] = *sl;
|
|
( *sl ) -> serial_num = serial_num++;
|
|
( *sl ) -> head = NULL;
|
|
( *sl ) -> tail = NULL;
|
|
( *sl ) -> elem_cnt = 0;
|
|
status = OK;
|
|
} /* end if */
|
|
} /* end if */
|
|
ui_print ( VDEBUG, "Leaving sci_new_list\n" );
|
|
return ( status );
|
|
} /* end sci_new_list */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_add_to_list_as_is
|
|
*/
|
|
int sci_add_to_list_as_is ( SCI_LIST sl, char * file_name )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
|
|
#ifndef NO_DEBUG
|
|
enter ( "sci_add_to_list_as_is" );
|
|
#endif
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
#ifndef NO_DEBUG
|
|
leave ( );
|
|
#endif
|
|
return ( ERROR );
|
|
} /* end if */
|
|
/*
|
|
* The F_OK access is to see if the file is present.
|
|
* If it is not present then it should not be added to the list
|
|
* if -changed or -saved is set.
|
|
*/
|
|
|
|
if ( file_mode == 0 || ( access ( file_name, F_OK ) == 0 &&
|
|
( ( file_mode == 1 && access ( file_name, W_OK) == 0 ) ||
|
|
( file_mode == 2 && access ( file_name, W_OK ) < 0 ))))
|
|
ui_print ( VDEBUG, "Adding %s to a list.\n", file_name );
|
|
else {
|
|
ui_print ( VDEBUG, "Skipping file %s.\n", file_name );
|
|
leave ( );
|
|
return ( OK );
|
|
} /* if */
|
|
sci_ptr = ( SCI_ELEM ) malloc ( (size_t) sizeof ( struct sci_elem ) );
|
|
if ( sci_ptr == NULL ) {
|
|
ui_print ( VFATAL, "alloc of sci_ptr failed.\n" );
|
|
leave ( );
|
|
return ( ERROR );
|
|
} /* end if */
|
|
sci_ptr -> name = strdup ( file_name );
|
|
sci_ptr -> ver_user = NULL;
|
|
sci_ptr -> ver_ancestor = NULL;
|
|
sci_ptr -> ver_config = NULL;
|
|
sci_ptr -> ver_merge = NULL;
|
|
sci_ptr -> ver_latest = NULL;
|
|
sci_ptr -> leader = NULL;
|
|
sci_ptr -> skip = FALSE;
|
|
sci_ptr -> locked = FALSE;
|
|
sci_ptr -> need_merge = FALSE;
|
|
sci_ptr -> merged_up = FALSE;
|
|
sci_ptr -> called_getancestor = FALSE;
|
|
sci_ptr -> defunct = FALSE;
|
|
sci_ptr -> status = OK;
|
|
sci_ptr -> same13 = FALSE;
|
|
sci_ptr -> same23 = FALSE;
|
|
sci_ptr -> has_user_branch = FALSE;
|
|
sci_ptr -> has_merge_branch = FALSE;
|
|
sci_ptr -> next = NULL;
|
|
if ( sl -> tail == NULL )
|
|
sl -> head = sci_ptr;
|
|
else
|
|
( sl -> tail ) -> next = sci_ptr;
|
|
/* end if */
|
|
sl -> tail = sci_ptr;
|
|
sl -> elem_cnt += 1;
|
|
#ifndef NO_DEBUG
|
|
leave ( );
|
|
#endif
|
|
return ( OK );
|
|
} /* end sci_add_to_list_as_is */
|
|
|
|
/*
|
|
* FUNCTION sci_add_to_list
|
|
*/
|
|
int sci_add_to_list ( SCI_LIST sl, char * file_name )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char buf [MAXPATHLEN];
|
|
char canonical_name [MAXPATHLEN];
|
|
|
|
#ifndef NO_DEBUG
|
|
enter ( "sci_add_to_list" );
|
|
#endif
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
#ifndef NO_DEBUG
|
|
leave ( );
|
|
#endif
|
|
return ( ERROR );
|
|
} /* end if */
|
|
ui_print ( VDEBUG, "Adding %s to a list.\n", file_name );
|
|
sci_ptr = ( SCI_ELEM ) malloc ( (size_t) sizeof ( struct sci_elem ) );
|
|
if ( sci_ptr == NULL ) {
|
|
ui_print ( VFATAL, "alloc of sci_ptr failed.\n" );
|
|
leave ( );
|
|
return ( ERROR );
|
|
} /* end if */
|
|
if (( *file_name == SLASH ) || /* absolute path; ./ beginning */
|
|
(( *file_name == PERIOD ) && (*( file_name + 1 ) == SLASH )) ||
|
|
( *org_path == NUL )) { /* not below src */
|
|
strcpy ( buf, file_name );
|
|
} else { /* relative path so use ./org_path/field */
|
|
concat ( buf, sizeof ( buf ), org_path, "/", file_name,
|
|
NULL );
|
|
} /* else */
|
|
/*
|
|
* This is messy, but it works for now.
|
|
*/
|
|
if ( canonicalize ( ".", buf, canonical_name, sizeof (canonical_name) )
|
|
!= OK ) {
|
|
leave ( );
|
|
return ( ERROR );
|
|
} /* end if */
|
|
sci_add_to_list_as_is ( sl, canonical_name );
|
|
leave ( );
|
|
return ( OK );
|
|
} /* end sci_add_to_list */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_first
|
|
*
|
|
* Give the first element in a given list
|
|
*/
|
|
SCI_ELEM
|
|
sci_first ( SCI_LIST sl )
|
|
{
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
log_error ( );
|
|
return ( NULL );
|
|
} /* end if */
|
|
return ( sl -> head );
|
|
} /* end sci_first */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_next
|
|
*
|
|
* Give the next element in a list from the element given.
|
|
*/
|
|
SCI_ELEM
|
|
sci_next ( SCI_ELEM se )
|
|
{
|
|
return ( se -> next );
|
|
} /* end sci_next */
|
|
|
|
int
|
|
sci_elem_cnt ( SCI_LIST sl )
|
|
{
|
|
return ( sl -> elem_cnt );
|
|
} /* end sci_elem_cnt */
|
|
|
|
/*
|
|
* FUNCTION sci_lookup_leader_list
|
|
*/
|
|
int sci_lookup_leader_list ( SCI_LIST sl )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char leader [MAXPATHLEN];
|
|
ERR_LOG log;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* end if */
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_get_comment_leader( sci_ptr -> name, leader ) == ERROR )
|
|
return( ERROR );
|
|
/* end if */
|
|
sci_ptr -> leader = strdup ( leader );
|
|
} /* end for */
|
|
log = oxm_close ( rcs_monitor );
|
|
|
|
return( OK );
|
|
} /* sci_lookup_leader_list */
|
|
|
|
/*
|
|
* FUNCTION sci_set_cmt_leader_list
|
|
*/
|
|
int sci_set_cmt_leader_list ( SCI_LIST sl, char * leader )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* end if */
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_set_comment_leader ( sci_ptr , leader ) == ERROR )
|
|
return( ERROR );
|
|
/* end if */
|
|
sci_ptr -> leader = strdup ( leader );
|
|
} /* end for */
|
|
log = oxm_close ( rcs_monitor );
|
|
return( OK );
|
|
} /* sci_set_cmt_leader_list */
|
|
|
|
|
|
/*
|
|
* In the old bsubmit, the code equivalent to sci_init was invoked multiple
|
|
* times. Once for each invokation of bci, bco, etc. Thus, bcsset
|
|
* was set multiple times. The following routine is a temporary
|
|
* kludge to accomplish the same thing for the two variables that require
|
|
* being set a second time.
|
|
*/
|
|
|
|
void
|
|
set_and_log_kludge ( char * set_name )
|
|
{
|
|
(void) concat(bcsset, sizeof(bcsset),
|
|
src_path, "/.BCSset-", set_name, NULL);
|
|
}
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_all_list
|
|
*
|
|
* Create a list of all files in a given set. The new list will
|
|
* be allocated. A new list does not need to be passed in, and
|
|
* will in fact be overwritten.
|
|
*/
|
|
int sci_all_list ( SCI_LIST * sl, char *set_name )
|
|
{
|
|
FILE * fp;
|
|
char filebuf [ PATH_LEN ], /* misc string */
|
|
tmp_buf [ PATH_LEN ], /* misc string */
|
|
* ptr_buff, /* misc ptr to char */
|
|
* set_file_name; /* name of set file */
|
|
|
|
ui_print ( VDEBUG, "In sci_all_list\n" );
|
|
sci_new_list ( sl );
|
|
if ( full_set_name ( &set_file_name, set_name ) == ERROR ) {
|
|
ui_print ( VDEBUG, "Leaving sci_all_list\n" );
|
|
return ( ERROR );
|
|
}
|
|
if (( fp = fopen ( set_file_name, READ )) == NULL ) {
|
|
ui_print ( VWARN, "No files in set.\n" );
|
|
ui_print ( VCONT, "Set: %s\n", set_name );
|
|
ui_print ( VCONT, "Set file: %s\n", set_file_name );
|
|
return ( ERROR );
|
|
}
|
|
while ( fgets ( filebuf, PATH_LEN, fp ) != NULL ) {
|
|
rm_newline ( filebuf );
|
|
strcpy ( tmp_buf, filebuf );
|
|
if (( ptr_buff = strdup ( tmp_buf )) == NULL ) {
|
|
ui_print ( VFATAL, "No room for strdup of: %s\n", tmp_buf );
|
|
ui_print ( VDEBUG, "Leaving sci_all_list\n" );
|
|
return ( ERROR );
|
|
}
|
|
if ( sci_add_to_list_as_is ( *sl, ptr_buff ) != OK ) {
|
|
return ( ERROR );
|
|
} /* end if */
|
|
} /* while */
|
|
fclose ( fp );
|
|
ui_print ( VDEBUG, "Leaving sci_all_list\n" );
|
|
return ( OK );
|
|
}
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_lookup_user_rev_list
|
|
*
|
|
* Provide user revisions for each file in a given list and a given set
|
|
*/
|
|
int sci_lookup_user_rev_list ( SCI_LIST sl, char * set_name,
|
|
int * missing_revs )
|
|
{
|
|
int status;
|
|
char buf [PATH_LEN];
|
|
char * buf_ptr;
|
|
char * ver_user;
|
|
char * def_str;
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_lookup_user_rev_list.\n" );
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* end if */
|
|
confirm_alloc ( sl );
|
|
status = OK;
|
|
* missing_revs = FALSE;
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
for (sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
#ifdef notdef
|
|
if ( sci_ptr -> skip )
|
|
continue;
|
|
/* end if */
|
|
#endif
|
|
src_ctl_lookup_revision ( sci_ptr -> name, set_name, buf, &log );
|
|
if ( log != OE_OK ) {
|
|
status = ERROR;
|
|
continue;
|
|
}
|
|
if ( buf == NULL || *buf == '\0' ) {
|
|
sci_ptr -> ver_user = NULL;
|
|
* missing_revs = TRUE;
|
|
} else {
|
|
buf_ptr = buf;
|
|
ver_user = nxtarg ( &buf_ptr, WHITESPACE );
|
|
def_str = nxtarg ( &buf_ptr, WHITESPACE );
|
|
if ( strcmp ( def_str, "(defunct)" ) == 0 ) {
|
|
ui_print ( VDEBUG, "version is defunct\n" );
|
|
sci_ptr -> defunct = TRUE;
|
|
} else if ( sci_ptr -> defunct ) {
|
|
ui_print ( VFATAL, "Contradiction between .BCSconfig file and\n" );
|
|
ui_print ( VCONT, "information in source control system\n" );
|
|
ui_print ( VCONT, "regarding defunct status.\n" );
|
|
ui_print ( VCONT, "For file: '%s'\n", sci_ptr -> name );
|
|
status = ERROR;
|
|
}
|
|
sci_ptr -> ver_user = strdup ( ver_user );
|
|
if ( sci_ptr -> ver_user == NULL ) {
|
|
ui_print ( VFATAL, "strdup of ver_user failed\n" );
|
|
status = ERROR;
|
|
break;
|
|
} /* end if */
|
|
} /* end if */
|
|
} /* end for */
|
|
log = oxm_close ( rcs_monitor );
|
|
ui_print ( VDEBUG, "Leaving sci_lookup_user_rev_list.\n" );
|
|
return ( status );
|
|
} /* sci_lookup_user_rev_list */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_lookup_latest_rev_list
|
|
*
|
|
* Provide user revisions for each file in a given list and a given set
|
|
*/
|
|
int sci_lookup_latest_rev_list ( SCI_LIST sl, char * set_name,
|
|
int * missing_revs)
|
|
{
|
|
int status = OK;
|
|
char buf [PATH_LEN];
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_lookup_latest_rev_list.\n" );
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
* missing_revs = FALSE;
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next) {
|
|
if ( sci_ptr -> defunct )
|
|
continue;
|
|
/* if */
|
|
src_ctl_lookup_revision ( sci_ptr -> name, set_name, buf, &log );
|
|
if ( buf == NULL || *buf == '\0' ) {
|
|
sci_ptr -> ver_latest = NULL;
|
|
* missing_revs = TRUE;
|
|
} else {
|
|
sci_ptr -> ver_latest = strdup ( buf );
|
|
if ( sci_ptr -> ver_latest == NULL ) {
|
|
ui_print ( VFATAL, "strdup of sci_ptr -> ver_latest failed.\n" );
|
|
status = ERROR;
|
|
break;
|
|
} /* if */
|
|
} /* if */
|
|
} /* for */
|
|
log = oxm_close ( rcs_monitor );
|
|
|
|
ui_print ( VDEBUG, "Leaving sci_lookup_latest_rev_list.\n" );
|
|
return ( status );
|
|
} /* sci_lookup_latest_rev_list */
|
|
|
|
/*
|
|
* FUNCTION sci_lookup_ancestor_rev_list
|
|
*
|
|
* Provide ancestor revisions for each file in a given list and a rev string
|
|
*/
|
|
int sci_lookup_ancestor_rev_list ( SCI_LIST sl, char * rev_str,
|
|
int * missing_revs )
|
|
{
|
|
int status = OK;
|
|
char buf [PATH_LEN];
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_lookup_ancestor_rev_list.\n" );
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
* missing_revs = FALSE;
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next) {
|
|
if ( sci_ptr -> defunct )
|
|
continue;
|
|
/* if */
|
|
src_ctl_lookup_revision ( sci_ptr -> name, rev_str, buf, &log );
|
|
if ( buf == NULL || *buf == '\0' ) {
|
|
sci_ptr -> ver_ancestor = NULL;
|
|
* missing_revs = TRUE;
|
|
} else {
|
|
sci_ptr -> ver_ancestor = strdup ( buf );
|
|
if ( sci_ptr -> ver_ancestor == NULL ) {
|
|
ui_print ( VFATAL, "strdup of sci_ptr -> ver_ancestor failed.\n" );
|
|
status = ERROR;
|
|
break;
|
|
} /* if */
|
|
sci_ptr -> need_merge = TRUE;
|
|
} /* if */
|
|
} /* for */
|
|
log = oxm_close ( rcs_monitor );
|
|
|
|
ui_print ( VDEBUG, "Leaving sci_lookup_latest_rev_list.\n" );
|
|
return ( status );
|
|
} /* sci_lookup_latest_rev_list */
|
|
|
|
/*
|
|
* FUNCTION sci_lookup_rev_list
|
|
*
|
|
* Provide revisions for each file in a given list
|
|
*/
|
|
int sci_lookup_rev_list ( SCI_LIST sl, char * rev_str, BOOLEAN which_rev,
|
|
int * missing_revs )
|
|
{
|
|
int status = OK;
|
|
char buf [PATH_LEN];
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
* missing_revs = FALSE;
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next) {
|
|
if ( sci_ptr -> defunct )
|
|
continue;
|
|
/* if */
|
|
src_ctl_lookup_revision ( sci_ptr -> name, rev_str, buf, &log );
|
|
if ( buf == NULL || *buf == '\0' ) {
|
|
if ( which_rev == REV_GENERIC1 )
|
|
sci_ptr -> ver_generic1 = NULL;
|
|
else if ( which_rev == REV_GENERIC1 )
|
|
sci_ptr -> ver_generic2 = NULL;
|
|
/* if */
|
|
* missing_revs = TRUE;
|
|
} else {
|
|
if ( which_rev == REV_GENERIC1 ) {
|
|
sci_ptr -> ver_generic1 = strdup ( buf );
|
|
if ( sci_ptr -> ver_generic1 == NULL ) {
|
|
ui_print ( VFATAL, "strdup of sci_ptr -> ver_generic1 failed.\n" );
|
|
status = ERROR;
|
|
break;
|
|
} /* if */
|
|
} else if ( which_rev == REV_GENERIC2 ) {
|
|
sci_ptr -> ver_generic2 = strdup ( buf );
|
|
if ( sci_ptr -> ver_generic2 == NULL ) {
|
|
ui_print ( VFATAL, "strdup of sci_ptr -> ver_generic2 failed.\n" );
|
|
status = ERROR;
|
|
break;
|
|
} /* if */
|
|
} /* if */
|
|
} /* if */
|
|
} /* for */
|
|
log = oxm_close ( rcs_monitor );
|
|
|
|
ui_print ( VDEBUG, "Leaving sci_lookup_rev_list.\n" );
|
|
return ( status );
|
|
} /* sci_lookup_rev_list */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_lookup_merge_rev_list
|
|
*
|
|
* Find the correct version to merge against ( whether an actual merge
|
|
* is necessary or not) .
|
|
*/
|
|
int sci_lookup_merge_rev_list ( SCI_LIST sl, char * rev_str,
|
|
char * config_str )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char rev1[32];
|
|
int status;
|
|
ERR_LOG log;
|
|
|
|
/*
|
|
* determine revision number for version to be merged with.
|
|
*/
|
|
status = OK;
|
|
enter ( "sci_lookup_merge_rev_list" );
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
for ( sci_ptr = sci_first ( sl ); sci_ptr != NULL;
|
|
sci_ptr = sci_next ( sci_ptr ) ) {
|
|
if ( src_ctl_lookup_revision( sci_ptr -> name, rev_str, rev1, &log) != 0 ) {
|
|
/*
|
|
ui_print ( VFATAL, "Revision %s not found\n", rev_str );
|
|
status = ERROR;
|
|
sci_ptr -> status = status;
|
|
*/
|
|
sci_ptr -> has_merge_branch = FALSE;
|
|
if ( src_ctl_lookup_revision ( sci_ptr -> name, config_str, rev1, &log )
|
|
!= 0 ) {
|
|
ui_print ( VFATAL, "Revision %s not found\n", rev_str );
|
|
status = ERROR;
|
|
sci_ptr -> status = status;
|
|
continue;
|
|
} /* end if */
|
|
} else
|
|
sci_ptr -> has_merge_branch = TRUE;
|
|
/* end if */
|
|
if ( strstr ( rev1, "(defunct)" ) != NULL ) {
|
|
sci_ptr -> defunct = TRUE;
|
|
status = ERROR;
|
|
ui_print ( VALWAYS, "File %s is defunct.\n", sci_ptr -> name );
|
|
} /* if */
|
|
sci_ptr -> ver_merge = strdup ( rev1 );
|
|
} /* end for */
|
|
/*
|
|
* Error from sci_first or sci_next ?
|
|
*/
|
|
if ( is_in_error ( ) )
|
|
status = ERROR;
|
|
/* end */
|
|
log = oxm_close ( rcs_monitor );
|
|
leave ( );
|
|
return ( status );
|
|
} /* end sci_lookup_merge_rev_list */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_ancestor_list
|
|
*
|
|
* Find the ancestors for the files given and determine if
|
|
* a merge is necessary
|
|
*/
|
|
int sci_ancestor_list ( SCI_LIST sl )
|
|
{
|
|
char rev1[32], rev2[32], rev3[32];
|
|
int status;
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
|
|
enter ( "sci_ancestor_list" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* end if */
|
|
status = OK;
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL;
|
|
sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> ver_user == NULL ) {
|
|
sci_ptr -> status = ERROR;
|
|
continue;
|
|
} /* end if */
|
|
if ( sci_ptr -> defunct ) {
|
|
continue;
|
|
} /* end if */
|
|
|
|
src_ctl_get_ancestry ( sci_ptr -> name, &(sci_ptr -> ancestry) );
|
|
|
|
/*
|
|
* determine revision number for "our" revision
|
|
*/
|
|
|
|
strcpy ( rev1, sci_ptr -> ver_merge );
|
|
strcpy ( rev2, sci_ptr -> ver_user );
|
|
|
|
rev3[0] = '\0';
|
|
|
|
if ( src_ctl_prep_merge ( rev1, rev2, rev3, sci_ptr ) != OK ) {
|
|
status = ERROR;
|
|
sci_ptr -> status = status;
|
|
continue;
|
|
}
|
|
} /* end while */
|
|
log = oxm_close ( rcs_monitor );
|
|
leave ();
|
|
return ( status );
|
|
} /* end sci_ancestor_list */
|
|
|
|
/*
|
|
* FUNCTION sci_is_branch
|
|
*
|
|
* Determine if the given revisions represent branches
|
|
*/
|
|
int
|
|
sci_is_branch ( SCI_LIST sl, int * bad_branches )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char * p;
|
|
int i;
|
|
int revision;
|
|
|
|
enter ( "sci_is_branch" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ( );
|
|
return ( ERROR );
|
|
} /* if */
|
|
*bad_branches = FALSE;
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> ver_user == NULL)
|
|
continue;
|
|
/* if */
|
|
i = 0;
|
|
for ( p = sci_ptr -> ver_user; *p != NUL ; p++ ) {
|
|
if ( *p == '.' ) {
|
|
i++;
|
|
if ( i == 3 ) {
|
|
p++;
|
|
break;
|
|
}
|
|
/* if */
|
|
} /* if */
|
|
} /* for */
|
|
if ( i == 3 ) {
|
|
ATOI ( revision, p );
|
|
} else
|
|
return ( ERROR );
|
|
/* if */
|
|
if ( revision > 1 )
|
|
sci_ptr -> has_user_branch = TRUE;
|
|
else
|
|
*bad_branches = TRUE;
|
|
/* if */
|
|
} /* for */
|
|
leave ( );
|
|
return ( OK );
|
|
} /* end sci_is_branch */
|
|
|
|
ERR_LOG
|
|
sci_check_in_elem ( SCI_ELEM sci_ptr, const char * build_set,
|
|
const char * user_set, const char * state )
|
|
{
|
|
char logmsg [LOGMSGSIZE];
|
|
ERR_LOG log = OE_OK;
|
|
int status = OK;
|
|
char branch_rev[32];
|
|
char * b_ptr;
|
|
BOOLEAN done;
|
|
char comma_v_file[MAXPATHLEN];
|
|
|
|
logmsg [0] = '\0';
|
|
begin_atomic ( );
|
|
if ( ! sci_local ) {
|
|
if ( copy_file ( sci_ptr -> name, temp_working_file, TRUE ) != 0) {
|
|
status = ERROR;
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* if */
|
|
} /* if */
|
|
if ( ! sci_has_log ( sci_ptr ) ) {
|
|
if ( create_leaderless_log ( sci_ptr -> name, user_set, logmsg,
|
|
mesgfile ) != OK) {
|
|
status = ERROR;
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* if */
|
|
} else if ( ! sci_ptr -> defunct ) {
|
|
if (( log = hst_lookup_logmsg( sci_ptr -> ver_user,
|
|
sci_ptr -> leader, TRUE,
|
|
sci_ptr -> ver_user, 1 ) ) != OE_OK) {
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* if */
|
|
if ( (log = okmesg ( sci_ptr -> leader, logmsg )) != OE_OK ) {
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* if */
|
|
} /* if */
|
|
/*
|
|
* If a branch already exists for the set we are submitting to, then
|
|
* we can just bump up the revision number. E.g., W.X.Y.Z goes to
|
|
* W.X.Y.Z+1. Otherwise, we need to create W.X.new branch.1, where
|
|
* NEWBRANCH is determined by src_ctl_create_branch. Then we can bump
|
|
* up the revision number as in the first case.
|
|
*/
|
|
if ( ! sci_ptr -> has_merge_branch ) {
|
|
done = FALSE;
|
|
strcpy ( branch_rev, sci_ptr -> ver_merge );
|
|
for ( b_ptr = branch_rev; *b_ptr != '\0'; b_ptr++) {
|
|
if (*b_ptr != '.')
|
|
continue;
|
|
/* if */
|
|
if ( done ) {
|
|
*b_ptr = '\0';
|
|
break;
|
|
} /* if */
|
|
done = TRUE;
|
|
} /* end for */
|
|
concat ( comma_v_file, sizeof(comma_v_file), sci_ptr -> name, ",v", NULL );
|
|
if ( sci_ptr -> defunct ) {
|
|
strcpy ( logmsg, "File is defunct" );
|
|
} /* if */
|
|
if ( src_ctl_create_branch2 ( temp_working_file, comma_v_file, FALSE,
|
|
branch_rev, build_set,
|
|
sci_ptr -> ver_ancestor, NULL, logmsg,
|
|
&log ) != OK) {
|
|
end_atomic ( );
|
|
if ( log == OE_OK ) {
|
|
return ( err_log ( OE_INTERNAL ) );
|
|
} /* if */
|
|
return ( log );
|
|
} /* if */
|
|
/*
|
|
* NOTE: branch_rev is an 'out' parameter. The old value from
|
|
* above is overwritten.
|
|
*/
|
|
if ( src_ctl_lookup_revision( sci_ptr -> name, build_set, branch_rev,
|
|
&log )
|
|
!= 0 ) {
|
|
ui_print ( VFATAL, "Could not find newly created branch\n" );
|
|
ui_print ( VCONT, "for set: '%s'.\n", build_set );
|
|
end_atomic ( );
|
|
return ( log );
|
|
} else
|
|
sci_ptr -> ver_merge = strdup ( branch_rev );
|
|
/* if */
|
|
} /* if */
|
|
|
|
/*
|
|
* The braces are necessary for this if statement. Do not remove them!
|
|
*/
|
|
if ( sci_ptr -> defunct ) {
|
|
if ( src_ctl_check_in ( sci_ptr -> name, sci_ptr -> ver_merge,
|
|
"File is defunct", "Defunct", &log )
|
|
!= OK || log != OE_OK ) {
|
|
end_atomic ( );
|
|
if ( log == OE_OK ) {
|
|
return ( err_log ( OE_INTERNAL ) );
|
|
} /* if */
|
|
return ( log );
|
|
} /* if */
|
|
} else {
|
|
if ( sci_ptr -> has_merge_branch ) {
|
|
if ( src_ctl_check_in ( sci_ptr -> name, sci_ptr -> ver_merge, logmsg ,
|
|
state, &log ) != OK || log != OE_OK ) {
|
|
end_atomic ( );
|
|
if ( log == OE_OK ) {
|
|
return ( err_log ( OE_INTERNAL ) );
|
|
} /* if */
|
|
return ( log );
|
|
} /* if */
|
|
} /* if */
|
|
if ( save_log_message( mesgfile ) != OE_OK) {
|
|
status = ERROR;
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* if */
|
|
(void) unlink(mesgfile);
|
|
if ( ! sci_local )
|
|
(void) unlink ( temp_working_file );
|
|
}/* if */
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* end sci_check_in_elem */
|
|
|
|
/*
|
|
* FUNCTION sci_check_in_list
|
|
*
|
|
* Check in given files.
|
|
*/
|
|
ERR_LOG
|
|
sci_check_in_list ( SCI_LIST sl, char * build_set, char * user_set,
|
|
char * state, BOOLEAN no_log )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
ERR_LOG e_log;
|
|
|
|
enter ( "sci_check_in_list" );
|
|
e_log = OE_OK;
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ( );
|
|
return ( err_log ( OE_ALLOC ) );
|
|
} /* if */
|
|
set_and_log_kludge ( build_set );
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( log );
|
|
/* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
}
|
|
check_path ( sci_ptr -> name );
|
|
if ( ( log = sci_check_in_elem ( sci_ptr, build_set, user_set, state ) )
|
|
!= OE_OK )
|
|
e_log = log;
|
|
/* if */
|
|
} /* end for */
|
|
if ( (log = oxm_close ( rcs_monitor ) ) != OE_OK )
|
|
e_log = log;
|
|
/* if */
|
|
leave ( );
|
|
return ( e_log );
|
|
} /* sci_check_in_list */
|
|
|
|
/*
|
|
* FIXME:
|
|
* sci_check_in_list2 is an alternate version of sci_check_in_list that
|
|
* works for bci. sci_check_in_list and sci_check_in_list2 should
|
|
* be merged at some point.
|
|
*/
|
|
int sci_check_in_list2 ( SCI_LIST sl, char * user_set, char * msg_str,
|
|
BOOLEAN defunct )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status = OK;
|
|
int tmp_status;
|
|
ERR_LOG log;
|
|
|
|
enter ( "sci_check_in_list2" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ( );
|
|
return ( ERROR );
|
|
} /* if */
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
temp_func ( sci_ptr );
|
|
if ( sci_has_log ( sci_ptr ) ) {
|
|
if ( ( log = hst_lookup_logmsg (
|
|
sci_ptr -> ver_user, sci_ptr -> leader,
|
|
FALSE, sci_ptr -> ver_user, 1 ) ) != OE_OK )
|
|
status = ERROR;
|
|
/* if */
|
|
/* if */
|
|
}
|
|
if ( ( tmp_status = real_check_in_file ( sci_ptr, user_set, msg_str,
|
|
defunct ) ) != OK )
|
|
status = tmp_status;
|
|
/* if */
|
|
} /* for */
|
|
log = oxm_close ( rcs_monitor );
|
|
leave ();
|
|
return ( status );
|
|
} /* sci_check_in_list2 */
|
|
|
|
int
|
|
temp_func ( SCI_ELEM sci_ptr )
|
|
{
|
|
check_path ( sci_ptr -> name );
|
|
if (copy_file(working_file, temp_working_file, TRUE) != 0) {
|
|
return ( ERROR );
|
|
} /* if */
|
|
return ( OK );
|
|
}
|
|
|
|
int
|
|
real_check_in_file ( SCI_ELEM sci_ptr, char * user_set, char * msg_str,
|
|
BOOLEAN defunct )
|
|
{
|
|
int improper;
|
|
int status;
|
|
int process_logs;
|
|
char logmsg [LOGMSGSIZE];
|
|
char * next_ver_user;
|
|
ERR_LOG log;
|
|
HIST_ELEM new_log;
|
|
HIST_ELEM history;
|
|
|
|
process_logs = FALSE;
|
|
logmsg [0] = '\0';
|
|
if ( sci_has_log ( sci_ptr ) ) {
|
|
process_logs = TRUE;
|
|
} /* if */
|
|
if ( process_logs || msg_str == NULL || *msg_str == '\0' ) {
|
|
if ( ( log = okmesg ( sci_ptr -> leader, logmsg ) ) != OE_OK ) {
|
|
status = ERROR;
|
|
} /* if */
|
|
} /* if */
|
|
if ( *logmsg == '\0' )
|
|
concat ( logmsg, LOGMSGSIZE, "\t", msg_str, NULL );
|
|
/* if */
|
|
if ( process_logs &&
|
|
( checklogstate ( temp_working_file, sci_ptr -> leader,
|
|
&improper ) != OK || improper )) {
|
|
ui_print ( VWARN, "Improper markers or history section in file %s\n",
|
|
sci_ptr->name);
|
|
return ( ERROR );
|
|
}
|
|
else {
|
|
if ( defunct ) {
|
|
src_ctl_check_in ( sci_ptr -> name, sci_ptr -> ver_user, logmsg,
|
|
"Defunct", &log );
|
|
(void) unlink ( working_file );
|
|
} else {
|
|
status = src_ctl_check_in ( sci_ptr -> name, sci_ptr -> ver_user,
|
|
logmsg, "Exp", &log );
|
|
if (status == 0) {
|
|
if (process_logs) {
|
|
next_ver_user = (char *)hst_next_revision(sci_ptr->ver_user);
|
|
new_log = hst_alloc_entry (sci_ptr -> leader, logmsg, next_ver_user);
|
|
free (next_ver_user);
|
|
history = hst_xtract_file (working_file, sci_ptr->leader);
|
|
new_log->next = history;
|
|
hst_insert_file (working_file, new_log, sci_ptr -> leader);
|
|
hst_freelist(new_log);
|
|
}
|
|
chmod ( sci_ptr -> name, S_IRUSR | S_IRGRP | S_IROTH );
|
|
} else {
|
|
ui_print (VALWAYS,
|
|
"Source control reported an error during check-in on file %s, history is not updated\n",
|
|
sci_ptr->name);
|
|
}
|
|
|
|
} /* if */
|
|
} /* if */
|
|
ui_print ( VNORMAL, "%s\n", sci_ptr -> name );
|
|
return ( OK );
|
|
} /* real_check_in_file */
|
|
|
|
int
|
|
sci_check_in_file ( SCI_ELEM sci_ptr, char * user_set, char * msg_str,
|
|
BOOLEAN defunct )
|
|
{
|
|
char buf [MAXPATHLEN];
|
|
char prompt [MAXPATHLEN];
|
|
char deflt [MAXPATHLEN];
|
|
char leader [MAXPATHLEN];
|
|
char *ptr;
|
|
FILE *inf;
|
|
int key;
|
|
int fd;
|
|
const char *def;
|
|
struct stat st;
|
|
ERR_LOG log;
|
|
char logmsg [LOGMSGSIZE];
|
|
BOOLEAN autoflag;
|
|
|
|
(void) unlink (mesgfile);
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
temp_func ( sci_ptr );
|
|
log = oxm_close ( rcs_monitor );
|
|
|
|
key = BA_XTRACT;
|
|
def = "xtract";
|
|
|
|
/*
|
|
* FIXME
|
|
* This module should know nothing about interface.c routines!
|
|
*/
|
|
autoflag = ui_is_auto ();
|
|
|
|
for (;;) {
|
|
switch (key) {
|
|
case BA_ABORT:
|
|
(void) unlink(temp_working_file);
|
|
return ( ABORT );
|
|
case BA_AUTO:
|
|
autoflag = TRUE;
|
|
break;
|
|
case BA_CHECKIN:
|
|
logmsg [0] = '\0';
|
|
if ( ( log = okmesg ( sci_ptr -> leader, logmsg ) ) == OE_OK ) {
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
real_check_in_file ( sci_ptr, user_set, msg_str, defunct );
|
|
log = oxm_close ( rcs_monitor );
|
|
return ( OK );
|
|
} else {
|
|
if ( err_type ( log ) == RECOVERABLE ) {
|
|
def = "log";
|
|
break;
|
|
} else
|
|
return ( ERROR );
|
|
/* if */
|
|
} /* if */
|
|
case BA_LEADER:
|
|
(void) concat(prompt, sizeof(prompt),
|
|
"Comment leader for ", canon_working_file, NULL);
|
|
(void) strcpy(deflt, (*(sci_ptr -> leader ) == NUL)
|
|
? "NONE" : sci_ptr -> leader);
|
|
for (;;) {
|
|
get_str(prompt, deflt, leader);
|
|
if (strcmp(leader, deflt) == 0)
|
|
break;
|
|
(void) strcpy(deflt, leader);
|
|
}
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
if (sci_set_comment_leader ( sci_ptr , leader) != 0)
|
|
return( ERROR );
|
|
/* if */
|
|
log = oxm_close ( rcs_monitor );
|
|
def = "xtract";
|
|
break;
|
|
case BA_XTRACT:
|
|
if ( sci_has_log ( sci_ptr ) )
|
|
if ( ( log = hst_lookup_logmsg (
|
|
sci_ptr -> ver_user, sci_ptr -> leader,
|
|
FALSE, sci_ptr -> ver_user, 1 ) ) != OE_OK )
|
|
if ( err_type ( log ) != RECOVERABLE )
|
|
return ( ERROR );
|
|
/* if */
|
|
/* if */
|
|
/* if */
|
|
if ( stat ( mesgfile, &st) == 0 && st.st_size > 0 ) {
|
|
def = "check-in";
|
|
} else if ( msg_str != NULL ) {
|
|
fd = open(mesgfile, O_WRONLY|O_TRUNC|O_CREAT, LOGMODE);
|
|
if (fd < 0) {
|
|
ui_print ( VFATAL, "open %s\n", mesgfile);
|
|
break;
|
|
}
|
|
if (write(fd, msg_str, strlen ( msg_str ) ) != strlen ( msg_str ) ) {
|
|
ui_print ( VFATAL, "write %s\n", mesgfile);
|
|
(void) close(fd);
|
|
(void) unlink(mesgfile);
|
|
break;
|
|
}
|
|
(void) close(fd);
|
|
def = "check-in";
|
|
} else {
|
|
ptr = concat(buf, sizeof(buf),
|
|
LOGPROMPT, " for ", canon_working_file, ">>>\n",
|
|
NULL);
|
|
fd = open(mesgfile, O_WRONLY|O_TRUNC|O_CREAT, LOGMODE);
|
|
if (fd < 0) {
|
|
ui_print ( VFATAL, "open %s\n", mesgfile);
|
|
break;
|
|
}
|
|
if (write(fd, buf, strlen ( buf ) ) != strlen ( buf ) ) {
|
|
ui_print ( VFATAL, "write %s\n", mesgfile);
|
|
(void) close(fd);
|
|
(void) unlink(mesgfile);
|
|
break;
|
|
}
|
|
(void) close(fd);
|
|
ui_print ( VALWAYS, "[ Please create a log message describing your changes ]\n");
|
|
def = "log";
|
|
autoflag = FALSE;
|
|
} /* if */
|
|
break;
|
|
case BA_DIFF:
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
src_ctl_diff_rev_with_file ( sci_ptr -> ver_user, temp_working_file,
|
|
sci_ptr -> name, -1, FALSE, FALSE, &log );
|
|
log = oxm_close ( rcs_monitor );
|
|
break;
|
|
case BA_EDIT:
|
|
(void) runp(EDIT_PROG, EDIT_PROG, temp_working_file, NULL);
|
|
if (stat(mesgfile, &st) < 0 || st.st_size == 0)
|
|
def = "xtract";
|
|
else
|
|
def = "check-in";
|
|
/* if */
|
|
break;
|
|
case BA_LOG:
|
|
(void) runp(EDIT_PROG, EDIT_PROG, mesgfile, NULL);
|
|
def = "check-in";
|
|
break;
|
|
case BA_LOGDIFF:
|
|
ptr = concat(buf, sizeof(buf),
|
|
LOGPROMPT, " for ", canon_working_file, ">>>\n",
|
|
NULL);
|
|
fd = open(mesgfile, O_WRONLY|O_TRUNC|O_CREAT, LOGMODE);
|
|
if (fd < 0) {
|
|
ui_print ( VWARN, "open %s\n", mesgfile);
|
|
break;
|
|
}
|
|
if (write(fd, buf, ptr-buf) != ptr-buf) {
|
|
ui_print ( VWARN, "write %s\n", mesgfile);
|
|
(void) close(fd);
|
|
(void) unlink(mesgfile);
|
|
break;
|
|
}
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
src_ctl_diff_rev_with_file( sci_ptr -> ver_user, temp_working_file,
|
|
sci_ptr -> name, fd, FALSE, FALSE, &log);
|
|
(void) close(fd);
|
|
log = oxm_close ( rcs_monitor );
|
|
def = "log";
|
|
break;
|
|
case BA_LIST:
|
|
if ((inf = fopen(mesgfile, "r")) == NULL) {
|
|
ui_print ( VWARN, "fopen %s\n", mesgfile);
|
|
break;
|
|
}
|
|
while (fgets(buf, sizeof(buf), inf) != NULL) {
|
|
(void) fputs( sci_ptr -> leader, stdout);
|
|
if (*buf != NUL && *buf != '\n') {
|
|
(void) putchar('\t');
|
|
}
|
|
(void) fputs(buf, stdout);
|
|
}
|
|
if (ferror(inf) || fclose(inf) == EOF) {
|
|
ui_print ( VWARN, "error reading %s\n", mesgfile);
|
|
(void) fclose(inf);
|
|
}
|
|
break;
|
|
case BA_HELP:
|
|
ui_print ( VALWAYS, "One of the following:\n\n");
|
|
ui_print ( VALWAYS, " abort - abort check-in\n");
|
|
ui_print ( VALWAYS, " auto - turn on automatic mode\n");
|
|
ui_print ( VALWAYS, " diff - diff working file with previous revision\n");
|
|
ui_print ( VALWAYS, " edit - edit working file\n");
|
|
ui_print ( VALWAYS, " check-in - check-in working file\n");
|
|
ui_print ( VALWAYS, " leader - set comment leader\n");
|
|
ui_print ( VALWAYS, " xtract - extract log message\n");
|
|
ui_print ( VALWAYS, " log - edit log message\n");
|
|
ui_print ( VALWAYS, " logdiff - use diffs for initial log message\n");
|
|
ui_print ( VALWAYS, " list - list log message\n");
|
|
break;
|
|
} /* switch */
|
|
if ( autoflag )
|
|
key = stablk ( def, bci_action, FALSE );
|
|
else
|
|
key = getstab("Command? (type \"help\" for a list)", bci_action, def);
|
|
/* if */
|
|
} /* for */
|
|
} /* sci_check_in_file */
|
|
|
|
/*
|
|
* FUNCTION sci_lock_list
|
|
*
|
|
* Lock given files
|
|
* Will not do a lock if sl -> has_merge_branch is FALSE.
|
|
*/
|
|
int
|
|
sci_lock_list ( SCI_LIST sl, int which_rev )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char tmp_buf [MAXPATHLEN];
|
|
int status = OK;
|
|
ERR_LOG log;
|
|
struct stat st;
|
|
|
|
enter ( "sci_lock_list" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* if */
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip ) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
} /* if */
|
|
concat ( tmp_buf, sizeof (tmp_buf), sci_ptr -> name, ",v" , NULL );
|
|
begin_atomic ( );
|
|
if ( which_rev == 1 ) {
|
|
if ( sci_ptr -> has_merge_branch )
|
|
if ( src_ctl_lock_revision ( sci_ptr -> ver_merge, tmp_buf, &log )
|
|
!= OK )
|
|
status = ERROR;
|
|
else
|
|
if ( submitting )
|
|
track_insert ( sci_ptr -> name );
|
|
/* if */
|
|
/* if */
|
|
/* if */
|
|
} else if ( which_rev == 2 ) {
|
|
if ( src_ctl_lock_revision ( sci_ptr -> ver_user, tmp_buf, &log )
|
|
!= OK )
|
|
status = ERROR;
|
|
/* if */
|
|
if (access( sci_ptr -> name, W_OK) < 0)
|
|
if (stat( sci_ptr -> name, &st) == 0)
|
|
if (chmod( sci_ptr -> name, (int)(st.st_mode|S_IWRITE)&MODEMASK)
|
|
< 0) {
|
|
ui_print ( VFATAL, "chmod %s\n", sci_ptr -> name);
|
|
status = ERROR;
|
|
} /* if */
|
|
/* if */
|
|
/* if */
|
|
} else if ( which_rev == 3 ) {
|
|
if ( src_ctl_lock_revision ( sci_ptr -> ver_latest, tmp_buf, &log )
|
|
!= OK )
|
|
status = ERROR;
|
|
/* if */
|
|
} /* if */
|
|
end_atomic ( );
|
|
} /* end for */
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
leave ();
|
|
return ( status );
|
|
} /* end sci_lock_list */
|
|
|
|
/*
|
|
* FUNCTION sci_merge_list
|
|
*
|
|
* This function and merge_elem are temporary kludges.
|
|
* They should be replaced with other functions such that
|
|
* the merging can be controlled externally.
|
|
*/
|
|
int
|
|
sci_merge_list ( SCI_LIST sl, BOOLEAN no_log )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status = OK;
|
|
int status2;
|
|
int m_e_status;
|
|
int fd;
|
|
ERR_LOG log;
|
|
|
|
enter ( "sci_merge_list" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ( );
|
|
return ( ERROR );
|
|
} /* if */
|
|
|
|
if (!temp_merge_setup)
|
|
src_ctl_setup_merge();
|
|
/* end if */
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
cnxtn_open = TRUE;
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip ) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
}
|
|
ui_print ( VALWAYS, "%s\n", sci_ptr -> name );
|
|
check_path ( sci_ptr -> name );
|
|
if ( sci_ptr -> defunct ) {
|
|
(void) unlink(temp2);
|
|
if ((fd = open(temp2, O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
|
|
ui_print ( VFATAL, "Unable to open %s for write", temp2);
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
status = ERROR;
|
|
continue;
|
|
}
|
|
ui_print ( VDETAIL, "Retrieving revision %s\n", sci_ptr -> ver_merge );
|
|
status2 = OK;
|
|
if ( src_ctl_check_out_with_fd( sci_ptr -> name, sci_ptr -> ver_merge,
|
|
fd, sci_ptr -> leader, &log) == ERROR)
|
|
status2 = ERROR;
|
|
/* if */
|
|
(void) close(fd);
|
|
if ( status2 != OK ) {
|
|
ui_print ( VFATAL, "Check out failed.\n", sci_ptr -> ver_user );
|
|
(void) unlink(temp1);
|
|
(void) unlink(temp2);
|
|
status = ERROR;
|
|
continue;
|
|
}
|
|
if (rename(temp2, temp_working_file) < 0) {
|
|
ui_print ( VFATAL, "Unable to rename %s to %s\n", temp2,
|
|
temp_working_file);
|
|
(void) unlink(temp2);
|
|
status = ERROR;
|
|
continue;
|
|
}
|
|
} else {
|
|
if ( submitting || sci_ptr -> need_merge ) {
|
|
m_e_status = merge_elem ( sci_ptr, no_log );
|
|
if ( m_e_status != OK ) {
|
|
status = m_e_status;
|
|
if ( status == ABORT )
|
|
break;
|
|
else
|
|
continue;
|
|
/* if */
|
|
} /* if */
|
|
} /* if */
|
|
sci_ptr -> merged_up = TRUE;
|
|
}
|
|
if ( submitting || sci_ptr -> need_merge ) {
|
|
if ( rename ( temp_working_file, sci_ptr -> name ) != 0) {
|
|
status = ERROR;
|
|
continue;
|
|
} /* if */
|
|
unlink ( temp_working_file );
|
|
} /* if */
|
|
#ifdef notdef
|
|
if ( submitting )
|
|
track_insert ( sci_ptr -> name );
|
|
/* if */
|
|
#endif
|
|
} /* end for */
|
|
|
|
if ( cnxtn_open )
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
ui_print ( VALWAYS, "Problem on close\n" );
|
|
return ( ERROR );
|
|
} /* if */
|
|
/* if */
|
|
|
|
leave ( );
|
|
return ( status );
|
|
} /* end sci_merge_list */
|
|
|
|
ERR_LOG
|
|
sci_update_build_file ( SCI_ELEM sci_ptr )
|
|
{
|
|
int status;
|
|
ERR_LOG log = OE_OK;
|
|
|
|
begin_atomic ( );
|
|
if ( sci_ptr -> defunct ) {
|
|
if ( remove_working_file ( FALSE ) != OK ) {
|
|
status = ERROR;
|
|
ui_print (VFATAL, "Unable to update %s in default build\n", sci_ptr->name);
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* end if */
|
|
} else {
|
|
if ( copy_file ( temp_working_file, sci_ptr -> name, FALSE ) != OK ) {
|
|
(void) unlink(temp_working_file);
|
|
status = ERROR;
|
|
ui_print (VFATAL, "Unable to update %s in default build\n", sci_ptr->name);
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* end if */
|
|
} /* end if */
|
|
end_atomic ( );
|
|
return ( log );
|
|
} /* end sci_update_build_file */
|
|
|
|
/*
|
|
* FUNCTION sci_update_build_list
|
|
*
|
|
* Update the backing build copies of the files. Either check them out
|
|
* or remove (defunct) them.
|
|
*/
|
|
int
|
|
sci_update_build_list ( SCI_LIST sl )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status = OK;
|
|
ERR_LOG log;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* if */
|
|
if ( ( log = oxm_open ( &src_monitor, SRC_MONITOR ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
}
|
|
check_path ( sci_ptr -> name );
|
|
sci_update_build_file ( sci_ptr );
|
|
} /* end for */
|
|
if ( ( log = oxm_close ( src_monitor ) ) != OE_OK ) {
|
|
return ( ERROR );
|
|
} /* if */
|
|
return ( status );
|
|
} /* end sci_update_build_list */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_outdate_list
|
|
*/
|
|
int
|
|
sci_outdate_list ( SCI_LIST sl, char * set_name )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status = OK;
|
|
char o_string[MAXPATHLEN];
|
|
int i;
|
|
const char *av[16];
|
|
char rcs_file_name [MAXPATHLEN];
|
|
char symbolic_name_switch [MAXPATHLEN];
|
|
ERR_LOG log;
|
|
|
|
enter ( "sci_outdate_list" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* end if */
|
|
set_and_log_kludge ( set_name );
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
}
|
|
concat ( o_string, sizeof ( o_string ), "-o:", sci_ptr -> ver_user, NULL );
|
|
i = 0;
|
|
concat ( rcs_file_name, sizeof ( rcs_file_name ), sci_ptr -> name,
|
|
",v", NULL );
|
|
concat ( symbolic_name_switch, sizeof ( symbolic_name_switch ), "-n",
|
|
set_name, NULL );
|
|
av[i++] = "outdate";
|
|
av[i++] = o_string;
|
|
av[i++] = symbolic_name_switch;
|
|
av[i++] = rcs_file_name;
|
|
av[i++] = NULL;
|
|
|
|
begin_atomic ( );
|
|
|
|
if ( ( log = oxm_runcmd ( rcs_monitor, i, av, NULL ) ) != OE_OK ) {
|
|
status = ERROR;
|
|
end_atomic ();
|
|
continue;
|
|
} /* if */
|
|
log = oxm_endcmd( rcs_monitor, &status);
|
|
|
|
if ( src_ctl_set_remove ( sci_ptr ) != OK ) {
|
|
status = ERROR;
|
|
end_atomic ();
|
|
continue;
|
|
}
|
|
if ( unlink ( sci_ptr -> name ) == 0 )
|
|
ui_print ( VDETAIL, "rm: removing %s\n", sci_ptr -> name);
|
|
/* end if */
|
|
if ( submitting )
|
|
track_insert ( sci_ptr -> name );
|
|
/* if */
|
|
end_atomic ( );
|
|
} /* end for */
|
|
log = oxm_close ( rcs_monitor );
|
|
leave ();
|
|
return ( status );
|
|
} /* end sci_outdate_list */
|
|
|
|
/*
|
|
* FUNCTION sci_outdate_list
|
|
*/
|
|
int
|
|
sci_outdate_list_p1 ( SCI_LIST sl, char * set_name )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status = OK;
|
|
ERR_LOG log;
|
|
|
|
enter ( "sci_outdate_list" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* end if */
|
|
set_and_log_kludge ( set_name );
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
}
|
|
if ( sci_ptr -> ver_user == NULL )
|
|
continue;
|
|
/* if */
|
|
src_ctl_outdate ( sci_ptr -> name, sci_ptr -> ver_user, set_name, FALSE );
|
|
if ( submitting )
|
|
track_insert ( sci_ptr -> name );
|
|
/* if */
|
|
ui_print ( VNORMAL, "%s\n", sci_ptr -> name );
|
|
end_atomic ( );
|
|
} /* end for */
|
|
log = oxm_close ( rcs_monitor );
|
|
leave ();
|
|
return ( status );
|
|
} /* end sci_outdate_list_p1 */
|
|
|
|
/*
|
|
* FUNCTION sci_outdate_list
|
|
*/
|
|
int
|
|
sci_outdate_list_p2 ( SCI_LIST sl, char * set_name )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status = OK;
|
|
|
|
enter ( "sci_outdate_list" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
leave ();
|
|
return ( ERROR );
|
|
} /* end if */
|
|
set_and_log_kludge ( set_name );
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> skip) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
}
|
|
|
|
if ( src_ctl_set_remove ( sci_ptr ) != OK ) {
|
|
status = ERROR;
|
|
end_atomic ();
|
|
continue;
|
|
}
|
|
if ( unlink ( sci_ptr -> name ) == 0 )
|
|
ui_print ( VDETAIL, "rm: removing %s\n", sci_ptr -> name);
|
|
/* end if */
|
|
ui_print ( VNORMAL, "rm: removing %s\n", sci_ptr -> name);
|
|
end_atomic ( );
|
|
} /* end for */
|
|
leave ();
|
|
return ( status );
|
|
} /* end sci_outdate_list_p2 */
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_trackfile
|
|
*
|
|
* The following function is a temporary kludge.
|
|
* externally to set the track file.
|
|
*/
|
|
void
|
|
sci_trackfile ( char * file_name, char * log_file )
|
|
{
|
|
ui_print ( VDEBUG, "Entering sci_trackfile\n" );
|
|
strcpy ( trackfile, file_name );
|
|
strcpy ( bcslog, log_file );
|
|
ui_print ( VDEBUG, "Leaving sci_trackfile\n" );
|
|
}
|
|
|
|
/*
|
|
* FUNCTION sci_config_lookup_list
|
|
*/
|
|
int
|
|
sci_config_lookup_list ( SCI_LIST sl )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
char config_rev [32];
|
|
int status;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* end if */
|
|
status = OK;
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( src_ctl_config_lookup ( sci_ptr, config_rev ) != OK ) {
|
|
status = ERROR;
|
|
continue;
|
|
}
|
|
sci_ptr -> ver_config = strdup ( config_rev );
|
|
} /* end if */
|
|
return ( status );
|
|
} /* end sci_config_lookup_list */
|
|
|
|
/*
|
|
* FUNCTION: sci_show_log_list
|
|
*/
|
|
ERR_LOG
|
|
sci_show_log_list ( SCI_LIST sl, BOOLEAN rev, BOOLEAN lock_users,
|
|
BOOLEAN header,
|
|
BOOLEAN rcs_path, BOOLEAN long_format )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
int status;
|
|
ERR_LOG log;
|
|
|
|
enter ( "sci_show_log_list" );
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( err_log ( OE_INTERNAL ) );
|
|
/* end if */
|
|
status = OK;
|
|
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK )
|
|
return ( log );
|
|
/* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( rev == REV_USER ) {
|
|
if ( sci_ptr -> ver_user == NULL ) {
|
|
ui_print ( VNORMAL, "%s has no branch for this sandbox.\n",
|
|
sci_ptr -> name );
|
|
} else {
|
|
if ( src_ctl_show_log ( sci_ptr -> name,
|
|
get_branch (sci_ptr -> ver_user),
|
|
lock_users, header, rcs_path,
|
|
long_format, &log ) != OK ) {
|
|
status = ERROR;
|
|
continue;
|
|
} /* if */
|
|
} /* if */
|
|
} else if ( rev == REV_LATEST ) {
|
|
if ( sci_ptr -> ver_latest == NULL ) {
|
|
ui_print ( VNORMAL, "%s does not contain the specified revision.\n",
|
|
sci_ptr -> name );
|
|
} else {
|
|
if ( src_ctl_show_log ( sci_ptr -> name,
|
|
get_branch ( sci_ptr -> ver_latest ),
|
|
lock_users, header, rcs_path,
|
|
long_format, &log ) != OK ) {
|
|
status = ERROR;
|
|
continue;
|
|
} /* if */
|
|
} /* if */
|
|
} else if ( rev == REV_ALL ) {
|
|
if ( src_ctl_show_log ( sci_ptr -> name,
|
|
NULL,
|
|
lock_users, header, rcs_path,
|
|
long_format, &log ) != OK ) {
|
|
status = ERROR;
|
|
continue;
|
|
} /* if */
|
|
} /* if */
|
|
} /* end if */
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK )
|
|
return ( log );
|
|
/* if */
|
|
if ( status == ERROR )
|
|
log = err_log ( OE_INTERNAL );
|
|
/* if */
|
|
leave ();
|
|
return ( log );
|
|
} /* end sci_show_log_list */
|
|
|
|
/*
|
|
* FUNCTION: sci_diff_rev_with_file
|
|
*/
|
|
ERR_LOG
|
|
sci_diff_rev_with_file ( SCI_LIST sl, BOOLEAN context, BOOLEAN whitespace )
|
|
{
|
|
ERR_LOG log;
|
|
SCI_ELEM sci_ptr;
|
|
struct stat statbuf;
|
|
char real_file[MAXPATHLEN];
|
|
char temp_file[MAXPATHLEN];
|
|
int status;
|
|
|
|
enter ( "sci_diff_rev_with_file" );
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if ( sci_ptr -> ver_generic1 == NULL) {
|
|
ui_print (VWARN, "There is no such revision associated \n");
|
|
ui_print (VCONT, "with file %s\n", sci_ptr->name);
|
|
continue;
|
|
}
|
|
|
|
status = lstat (sci_ptr->name, &statbuf);
|
|
if ((statbuf.st_mode & S_IFMT) == S_IFLNK) {
|
|
/* Follow all links to a regular file. */
|
|
strcpy (temp_file, sci_ptr->name);
|
|
for(;;) {
|
|
readlink (temp_file, real_file, MAXPATHLEN);
|
|
status = lstat (real_file, &statbuf);
|
|
if (status != 0) {
|
|
break;
|
|
} else if ((statbuf.st_mode & S_IFMT) == S_IFREG) {
|
|
break;
|
|
} else if ((statbuf.st_mode & S_IFMT) == S_IFLNK)
|
|
strcpy(temp_file, real_file);
|
|
}
|
|
if (status != 0) {
|
|
ui_print (VWARN,
|
|
"Cannot check differences on file %s\n",
|
|
sci_ptr->name);
|
|
} else {
|
|
check_path ( real_file );
|
|
src_ctl_diff_rev_with_file ( sci_ptr -> ver_generic1, real_file,
|
|
sci_ptr -> name, -1, context,
|
|
whitespace, &log );
|
|
}
|
|
|
|
} else {
|
|
/* Regular file */
|
|
check_path ( sci_ptr -> name );
|
|
src_ctl_diff_rev_with_file ( sci_ptr -> ver_generic1, working_file,
|
|
sci_ptr -> name, -1, context,
|
|
whitespace, &log );
|
|
}
|
|
} /* for */
|
|
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
leave ();
|
|
return ( log );
|
|
} /* end sci_diff_rev_with_file */
|
|
|
|
/*
|
|
* FUNCTION: sci_diff_rev_with_rev
|
|
*/
|
|
ERR_LOG
|
|
sci_diff_rev_with_rev ( SCI_LIST sl, BOOLEAN context, BOOLEAN whitespace )
|
|
{
|
|
ERR_LOG log;
|
|
SCI_ELEM sci_ptr;
|
|
|
|
enter ( "sci_diff_rev_with_rev" );
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
if (sci_ptr->ver_generic1 == NULL) {
|
|
ui_print (VWARN,
|
|
"The revision specified with the '-r' option cannot\n");
|
|
ui_print (VCONT,
|
|
"be found in file %s\n", sci_ptr->name);
|
|
continue;
|
|
}
|
|
if (sci_ptr->ver_generic2 == NULL) {
|
|
ui_print (VWARN,
|
|
"The revision specified with the '-R' option cannot\n");
|
|
ui_print (VCONT,
|
|
"be found in file %s\n", sci_ptr->name);
|
|
continue;
|
|
}
|
|
check_path ( sci_ptr -> name );
|
|
src_ctl_show_diffs ( sci_ptr -> ver_generic1, sci_ptr -> ver_generic2,
|
|
sci_ptr -> name, context, whitespace, &log );
|
|
} /* for */
|
|
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
leave ();
|
|
return ( log );
|
|
} /* end sci_diff_rev_with_rev */
|
|
|
|
/*
|
|
* FUNCTION: sci_set_symbol_list
|
|
*/
|
|
ERR_LOG
|
|
sci_set_symbol_list ( SCI_LIST sl, char * sym_str, BOOLEAN override )
|
|
{
|
|
ERR_LOG log;
|
|
SCI_ELEM sci_ptr;
|
|
|
|
enter ( "sci_set_symbol_list" );
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_ptr -> next ) {
|
|
log = (ERR_LOG) src_ctl_add_symbol ( sci_ptr -> name, sym_str, override );
|
|
if ( log != OE_OK )
|
|
ui_print ( VFATAL, "%s\n", err_str ( log ) );
|
|
/* if */
|
|
} /* for */
|
|
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
leave ();
|
|
return ( OE_OK );
|
|
} /* end sci_set_symbol_list */
|
|
|
|
extern int oxm_local;
|
|
|
|
ERR_LOG
|
|
sci_submit ( SCI_LIST file_set, char * build_set, char * user_set,
|
|
BOOLEAN info )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
ERR_LOG log;
|
|
char tempfile [MAXPATHLEN];
|
|
char tempdir [MAXPATHLEN];
|
|
int status;
|
|
|
|
enter ( "sci_submit" );
|
|
if ( ! info ) {
|
|
oxm_local = TRUE;
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
oxm_local = FALSE;
|
|
if ( ( log = oxm_open ( &src_monitor, SRC_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
|
|
strcpy ( tempfile , "dummy" );
|
|
temp_working_file[0] = '\0';
|
|
strcpy ( tempdir, "#srvtmpXXXXXX" );
|
|
opentemp ( tempdir , tempdir );
|
|
(void) concat(mesgfile, sizeof(mesgfile), tempdir, "/_LOG_", NULL);
|
|
} else {
|
|
ui_print ( VNORMAL, "Would submit the following files:\n" );
|
|
log = OE_OK;
|
|
} /* if */
|
|
for ( sci_ptr = file_set -> head; sci_ptr != NULL; sci_ptr = sci_ptr-> next) {
|
|
if ( sci_ptr -> skip ) {
|
|
sci_ptr -> skip = FALSE;
|
|
continue;
|
|
} /* if */
|
|
check_path ( sci_ptr -> name );
|
|
if ( !info ) {
|
|
oxm_local = TRUE;
|
|
sci_local = TRUE;
|
|
concat ( temp_working_file, sizeof(temp_working_file), tempdir,
|
|
"/", working_file_tail, NULL );
|
|
if ( ( status = src_ctl_check_out( sci_ptr -> name, sci_ptr -> ver_user,
|
|
sci_ptr -> leader, &log ) ) != 0 ) {
|
|
leave ();
|
|
return ( err_log ( OE_INTERNAL ) );
|
|
} /* if */
|
|
if ( log != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
if ( ( log = sci_check_in_elem ( sci_ptr, build_set, user_set, "Exp" ) )
|
|
!= OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
sci_local = FALSE;
|
|
oxm_local = FALSE;
|
|
if ( ( log = sci_update_build_file ( sci_ptr ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
track_insert ( sci_ptr -> name );
|
|
unlink ( temp_working_file );
|
|
} /* if */
|
|
ui_print ( VNORMAL, "%s\n", sci_ptr -> name );
|
|
} /* for */
|
|
if ( !info ) {
|
|
rmdir ( tempdir );
|
|
|
|
oxm_local = FALSE;
|
|
if ( ( log = oxm_close ( src_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
oxm_local = TRUE;
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
oxm_local = FALSE;
|
|
} /* if */
|
|
leave();
|
|
return ( log );
|
|
} /* end sci_submit */
|
|
|
|
ERR_LOG
|
|
sci_rm_submit ( SCI_LIST file_set, char * set_name )
|
|
{
|
|
ERR_LOG log;
|
|
ERR_LOG e_log;
|
|
SCI_ELEM sci_ptr;
|
|
int status;
|
|
char logmsg [MAXPATHLEN];
|
|
char ver_latest [MAXPATHLEN];
|
|
char tempfile [MAXPATHLEN];
|
|
char tempdir [MAXPATHLEN];
|
|
|
|
if ( ! confirm_alloc ( file_set ) )
|
|
return ( (ERR_LOG) OE_INTERNAL );
|
|
/* if */
|
|
enter ( "sci_rm_submit" );
|
|
oxm_local = TRUE;
|
|
if ( ( log = oxm_open ( &rcs_monitor, RCS_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
oxm_local = FALSE;
|
|
if ( ( log = oxm_open ( &src_monitor, SRC_MONITOR ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
|
|
strcpy ( tempfile , "dummy" );
|
|
temp_working_file[0] = '\0';
|
|
strcpy ( tempdir, "#srvtmpXXXXXX" );
|
|
opentemp ( tempdir , tempdir );
|
|
|
|
for ( sci_ptr = file_set -> head; sci_ptr != NULL; sci_ptr = sci_ptr-> next) {
|
|
if ( sci_ptr -> skip )
|
|
continue;
|
|
/* if */
|
|
check_path ( sci_ptr -> name );
|
|
sci_local = TRUE;
|
|
oxm_local = TRUE;
|
|
concat ( temp_working_file, sizeof(temp_working_file), tempdir,
|
|
"/", working_file_tail, NULL );
|
|
src_ctl_check_out ( sci_ptr -> name, sci_ptr -> ver_merge,
|
|
sci_ptr -> leader, &log );
|
|
strcpy ( logmsg, "\tCover submission to restore file to previous state" );
|
|
if ( src_ctl_check_in ( sci_ptr -> name, sci_ptr -> ver_latest, logmsg ,
|
|
"Exp", &log ) != OK ) {
|
|
e_log = log;
|
|
} /* if */
|
|
src_ctl_lookup_revision ( sci_ptr -> name, set_name, ver_latest, &log );
|
|
#ifdef notdef
|
|
src_ctl_check_out ( sci_ptr -> name, ver_latest,
|
|
sci_ptr -> leader, &log );
|
|
#endif
|
|
sci_local = FALSE;
|
|
oxm_local = FALSE;
|
|
if ( copy_file ( temp_working_file, sci_ptr -> name, FALSE ) != OK ) {
|
|
(void) unlink(temp_working_file);
|
|
status = ERROR;
|
|
ui_print (VFATAL, "Unable to update %s in default build\n",
|
|
sci_ptr->name);
|
|
end_atomic ( );
|
|
continue;
|
|
} /* end if */
|
|
(void) unlink(temp_working_file);
|
|
ui_print ( VNORMAL, "%s\n", sci_ptr -> name );
|
|
} /* for */
|
|
|
|
oxm_local = FALSE;
|
|
if ( ( log = oxm_close ( src_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
oxm_local = TRUE;
|
|
if ( ( log = oxm_close ( rcs_monitor ) ) != OE_OK ) {
|
|
leave ();
|
|
return ( log );
|
|
} /* if */
|
|
oxm_local = FALSE;
|
|
leave ();
|
|
return ( OE_OK );
|
|
} /* end sci_rm_submit */
|
|
|
|
/****************************** New sci functions *************************/
|
|
/* Note: some of these functions are not currently used. Some of the ones */
|
|
/* that aren't being used don't work. */
|
|
/****************************** New sci functions *************************/
|
|
|
|
STATIC
|
|
char * tmpfile_name(char * );
|
|
|
|
STATIC
|
|
int tmpfile_create(char * );
|
|
|
|
STATIC
|
|
void
|
|
tmpfile_delete(char * );
|
|
|
|
STATIC
|
|
char * tmpfile_base(void);
|
|
|
|
STATIC
|
|
char * tail_pathname(char *);
|
|
|
|
/*
|
|
* PROCEDURE sci_create_files ()
|
|
*
|
|
* ARGUMENTS: A list of files (in the structure SCI_LIST) to place under
|
|
* source control.
|
|
*
|
|
* PURPOSE - Given a list of file names. This procedure will place those
|
|
* files under source control. If the files to place under
|
|
* source control do not exist in the sandbox, then a file
|
|
* is created in the sandbox with a copyright
|
|
* marker and history section.
|
|
*
|
|
*/
|
|
int
|
|
sci_create_files ( SCI_LIST sl, const char * copy_name,
|
|
BOOLEAN check_copyrights )
|
|
{
|
|
SCI_ELEM sl_elem;
|
|
char * tail_name;
|
|
|
|
FILE *fbuf;
|
|
struct stat st;
|
|
|
|
int i, ii = 0;
|
|
int fd;
|
|
const char *av[16];
|
|
char rcs_file[MAXPATHLEN];
|
|
ERR_LOG log;
|
|
int status;
|
|
struct stat statb;
|
|
char * ptr;
|
|
|
|
if (check_copyrights == TRUE) {
|
|
if (copy_name == NULL)
|
|
copy_name = "DEFAULT";
|
|
|
|
for (ii = 0; ii < valid_copyrights; ii++) {
|
|
if (strcmp(copy_name, copyright_name[ii]) == 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
sl_elem = sci_first ( sl );
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
while ( sl_elem != NULL ) {
|
|
|
|
if (src_ctl_file_exists(sl_elem->name, &log) == 0) {
|
|
ui_print (VALWAYS,
|
|
"File %s is already under source control.\n",
|
|
sl_elem->name);
|
|
} else {
|
|
|
|
tail_name = (char *) tail_pathname (sl_elem->name);
|
|
|
|
/*
|
|
* Set up temporary file.
|
|
*/
|
|
fd = tmpfile_create( sl_elem->name );
|
|
close ( fd );
|
|
|
|
/* Set up for remote execution. */
|
|
concat (rcs_file, sizeof(rcs_file), sl_elem->name, ",v", NULL);
|
|
|
|
i = 0;
|
|
av[i++] = "rcs";
|
|
av[i++] = "-U";
|
|
av[i++] = "-q";
|
|
av[i++] = "-i";
|
|
av[i++] = "-t/dev/null";
|
|
av[i++] = rcs_file;
|
|
log = oxm_runcmd ( rcs_monitor, i, av, NULL );
|
|
log = oxm_endcmd( rcs_monitor, &status );
|
|
|
|
i = 0;
|
|
av[i++] = "-t2";
|
|
av[i++] = "6";
|
|
av[i++] = "ci";
|
|
av[i++] = "-q";
|
|
av[i++] = "-f";
|
|
av[i++] = "-u1.1";
|
|
av[i++] = "-d01-Jan-1990 00:00:00";
|
|
av[i++] = "-m*** Initial Trunk Revision ***";
|
|
av[i++] = tail_name;
|
|
av[i++] = rcs_file;
|
|
log = oxm_runcmd ( rcs_monitor, i, av, tmpfile_base() );
|
|
log = oxm_endcmd( rcs_monitor, &status );
|
|
/* End of remote execution. */
|
|
|
|
/* Set the comment leader. */
|
|
if (sl_elem->leader == NULL)
|
|
sl_elem->leader= (char *)"NONE";
|
|
|
|
|
|
/* Create a branch off the initial revision "1.1". */
|
|
check_path ( sl_elem -> name );
|
|
src_ctl_create_branch ( sl_elem -> name, "1.1", sl_elem -> set, NULL,
|
|
sl_elem -> leader, &log );
|
|
set_insert ( );
|
|
/* Set up the working file in the sandbox. */
|
|
/**********************************************************************/
|
|
/*********** This section of code should be moved somewhere else *****/
|
|
if (access(sl_elem->name, F_OK) == 0) {
|
|
ui_print(VALWAYS, "[ %s already exists, not modified ]\n",
|
|
sl_elem->name);
|
|
if (access(sl_elem->name, W_OK) < 0) {
|
|
if (stat(sl_elem->name, &st) < 0)
|
|
ui_print (VALWAYS,
|
|
"Unable to fix access rights on %s",
|
|
sl_elem->name);
|
|
else if (chmod(sl_elem->name,
|
|
(int)(st.st_mode|S_IWRITE)&0777) < 0)
|
|
ui_print (VALWAYS,
|
|
"Unable to fix access rights on %s",
|
|
sl_elem->name);
|
|
}
|
|
} else {
|
|
|
|
/* File does not exist. Create a new file
|
|
with appropriate header. */
|
|
if (stat(working_file_dir, &statb) < 0) {
|
|
if (makedir(working_file_dir) != 0)
|
|
return( ERROR );
|
|
} else if ((statb.st_mode&S_IFMT) != S_IFDIR) {
|
|
ui_print ( VFATAL, "%s: not a directory\n", working_file_dir);
|
|
return( ERROR );
|
|
}
|
|
if ((fbuf = fopen(sl_elem->name, "w")) == NULL) {
|
|
ui_print (VALWAYS, "unable to open %s for writing",
|
|
sl_elem->name);
|
|
} else {
|
|
if ((sl_elem->leader != NULL) &&
|
|
sci_has_log ( sl_elem ) ) {
|
|
if (strcmp(sl_elem->leader, " * ") == 0 )
|
|
fprintf(fbuf,"/*\n");
|
|
|
|
if (check_copyrights == FALSE) {
|
|
fprintf (fbuf,"%s%s\n", sl_elem->leader,
|
|
default_copyright());
|
|
fprintf (fbuf, "%s", sl_elem->leader);
|
|
} else {
|
|
fprintf (fbuf,"%sCOPYRIGHT NOTICE\n", sl_elem->leader);
|
|
fprintf (fbuf, "%s", sl_elem->leader);
|
|
for (ptr = raw_copyright_list[ii]; ((ptr != NULL) && (*ptr != '\0'));
|
|
) {
|
|
if (*ptr == '\n') {
|
|
fprintf (fbuf, "\n");
|
|
fprintf (fbuf, "%s", sl_elem->leader);
|
|
ptr++;
|
|
} else if ( (strlen(ptr) >= 7) &&
|
|
(strncmp(ptr, "@YEARS@", 7) == 0) ) {
|
|
if (copyright_years != NULL)
|
|
fprintf (fbuf, "%s", copyright_years);
|
|
else
|
|
ui_print (VWARN, "Variable copyright_years is not defined in the resource files.\n");
|
|
ptr = ptr + 7;
|
|
} else {
|
|
fprintf (fbuf, "%c", *ptr);
|
|
ptr++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (strcmp(sl_elem->leader, " * ") == 0 ) {
|
|
fprintf(fbuf,"\n */\n");
|
|
fprintf(fbuf,"/*\n");
|
|
} else
|
|
fprintf(fbuf,"\n%s\n",sl_elem->leader);
|
|
fprintf(fbuf,"%sHISTORY\n",sl_elem->leader);
|
|
/* the following line has to be written in two pieces to keep
|
|
it from being expanded by RCS */
|
|
fprintf(fbuf,"%s$Lo",sl_elem->leader);
|
|
fprintf(fbuf,"g: $\n");
|
|
fprintf(fbuf,"%s$EndLog$\n",sl_elem->leader);
|
|
if (strcmp(sl_elem->leader, " * ") == 0 )
|
|
fprintf(fbuf," */\n");
|
|
fclose(fbuf);
|
|
}
|
|
}
|
|
}
|
|
/*********************************************************************/
|
|
|
|
tmpfile_delete ( sl_elem->name );
|
|
}
|
|
ui_print ( VNORMAL, "%s created.\n", sl_elem->name );
|
|
sl_elem = sci_next ( sl_elem );
|
|
}
|
|
log = oxm_close ( rcs_monitor );
|
|
return ( OK );
|
|
}
|
|
|
|
/*
|
|
* PROCEDURE sci_delete_files ()
|
|
*
|
|
* ARGUMENTS: A list of files (in the structure SCI_LIST) to remove from
|
|
* source control.
|
|
*
|
|
* PURPOSE - Given a list of file names. This procedure will "undo"
|
|
* a file(s) that has just been created.
|
|
*
|
|
*/
|
|
ERR_LOG
|
|
sci_delete_files ( SCI_LIST sl, char * set_name )
|
|
{
|
|
SCI_ELEM sl_elem;
|
|
ERR_LOG log;
|
|
|
|
sl_elem = sci_first ( sl );
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
while ( sl_elem != NULL ) {
|
|
check_path ( sl_elem -> name );
|
|
bcreate_undo ( sl_elem, set_name );
|
|
sl_elem = sci_next ( sl_elem );
|
|
}
|
|
log = oxm_close ( rcs_monitor );
|
|
return ( log );
|
|
}
|
|
|
|
STATIC
|
|
char *
|
|
tail_pathname ( char * pathname )
|
|
{
|
|
|
|
char *tail;
|
|
char *cptr;
|
|
int i,
|
|
len;
|
|
/*
|
|
return ( working_file_tail );
|
|
*/
|
|
/* If we're passed a null pointer or a pointer to an empty string
|
|
then pass back an empty string. */
|
|
if ((pathname == NULL) || (*pathname == '\0'))
|
|
return ((char *)"");
|
|
|
|
|
|
/* Extract the last component of 'pathname'. */
|
|
|
|
|
|
/* Find the end of the string. */
|
|
for (i = 0, cptr = pathname; *cptr != '\0'; i++, cptr++);
|
|
|
|
/* Go back to the last component in the pathname ('/') or beginning of
|
|
the string. */
|
|
for (len = 0; (i != 0) && (*cptr != '/') ; len++, cptr--, i--);
|
|
|
|
/* Adjust pointer */
|
|
if ( *cptr == '/' ) {
|
|
cptr++;
|
|
len--;
|
|
}
|
|
|
|
tail = (char *)malloc ( (size_t) (len + 1) );
|
|
|
|
strcpy (tail, cptr);
|
|
|
|
return (tail);
|
|
}
|
|
|
|
int
|
|
sci_read_files ( SCI_LIST sl, char * revision )
|
|
{
|
|
SCI_ELEM sl_elem;
|
|
char * selected_rev;
|
|
ERR_LOG log;
|
|
BOOLEAN defunct;
|
|
struct stat st;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* end if */
|
|
sl_elem = sci_first ( sl );
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
while ( sl_elem != NULL ) {
|
|
check_path ( sl_elem -> name );
|
|
sci_read_file ( sl_elem->name, revision, &selected_rev, &defunct, &log );
|
|
if ( log == OE_OK ) {
|
|
stat ( sl_elem->name, &st );
|
|
chmod ( sl_elem->name, ( st.st_mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) | S_IRUSR | S_IRGRP | S_IROTH );
|
|
ui_print ( VNORMAL , "%s\n", sl_elem -> name );
|
|
/* Select next element for processing. */
|
|
} /* if */
|
|
sl_elem = sci_next ( sl_elem );
|
|
}
|
|
log = oxm_close ( rcs_monitor );
|
|
return (OK);
|
|
}
|
|
|
|
void
|
|
sci_read_file ( char * pathname, char * rev_str, char ** selected_rev,
|
|
BOOLEAN * defunct, ERR_LOG * log )
|
|
{
|
|
int i;
|
|
const char *av[16];
|
|
char *rev_arg;
|
|
char rcs_file[MAXPATHLEN];
|
|
int status;
|
|
char revision [32];
|
|
char *tempfile;
|
|
/*
|
|
* FIXME: redundant?
|
|
if (src_ctl_file_exists(pathname, &log) != 0) {
|
|
ui_print (VALWAYS,
|
|
"File %s is not under source control.\n",
|
|
pathname);
|
|
return;
|
|
}
|
|
*/
|
|
if ( src_ctl_lookup_revision ( pathname, rev_str, revision, log ) != 0 ) {
|
|
ui_print ( VWARN, "File does not contain the revision specified. \n" );
|
|
ui_print ( VCONT, "File: %s\n", pathname );
|
|
ui_print ( VCONT, "Revision: %s\n", rev_str );
|
|
*log = err_log ( OE_REVISION );
|
|
return;
|
|
} /* if */
|
|
|
|
*selected_rev = strdup ( revision );
|
|
if ( strstr ( revision, "defunct" ) != NULL ) {
|
|
*defunct = TRUE;
|
|
return;
|
|
} /* if */
|
|
*defunct = FALSE;
|
|
tmpfile_delete ( pathname );
|
|
/*
|
|
tail = tail_pathname (pathname);
|
|
*/
|
|
concat (rcs_file, sizeof(rcs_file), pathname, ",v", NULL);
|
|
rev_arg = alloc_switch('r', revision );
|
|
|
|
i = 0;
|
|
av[i++] = "-t0";
|
|
av[i++] = "3";
|
|
av[i++] = "co";
|
|
av[i++] = "-q";
|
|
av[i++] = rev_arg;
|
|
av[i++] = working_file_tail;
|
|
av[i++] = rcs_file;
|
|
*log = oxm_runcmd ( rcs_monitor, i, av, tmpfile_base () );
|
|
*log = oxm_endcmd ( rcs_monitor, &status );
|
|
/* Copy the file into the sandbox. */
|
|
(void) unlink (pathname);
|
|
tempfile = tmpfile_name(pathname);
|
|
makedir ( working_file_dir );
|
|
rename ( tempfile, pathname );
|
|
free(tempfile);
|
|
free(rev_arg);
|
|
}
|
|
|
|
void
|
|
trunk_revision ( char * full_rev, char ** trunk_rev )
|
|
{
|
|
int first;
|
|
char * rev;
|
|
/*
|
|
* Keep only the first two fields of revision
|
|
*/
|
|
|
|
*trunk_rev = strdup ( full_rev );
|
|
first = FALSE;
|
|
for (rev = *trunk_rev; *rev != '\0'; rev++) {
|
|
if (*rev != '.')
|
|
continue;
|
|
if (first) {
|
|
*rev = '\0';
|
|
break;
|
|
}
|
|
first = TRUE;
|
|
}
|
|
} /* trunk_revision */
|
|
|
|
ERR_LOG
|
|
sci_select_not_exists ( SCI_LIST file_set, SCI_LIST * files_not_exist )
|
|
{
|
|
SCI_ELEM sci_ptr;
|
|
SCI_ELEM sci_tmp;
|
|
|
|
sci_new_list ( files_not_exist );
|
|
for ( sci_ptr = sci_first ( file_set ); sci_ptr != NULL;
|
|
sci_ptr = sci_next ( sci_ptr ) )
|
|
if ( ! sci_ptr -> exists ) {
|
|
sci_tmp = (SCI_ELEM) malloc ( (size_t) sizeof ( struct sci_elem ) );
|
|
memcpy ( (void *)sci_tmp, (void *)sci_ptr,
|
|
sizeof ( struct sci_elem ) );
|
|
if ( (*files_not_exist) -> tail == NULL )
|
|
(*files_not_exist) -> head = sci_tmp;
|
|
else
|
|
( (*files_not_exist) -> tail ) -> next = sci_tmp;
|
|
/* end if */
|
|
(*files_not_exist) -> tail = sci_tmp;
|
|
(*files_not_exist) -> elem_cnt += 1;
|
|
} /* if */
|
|
/* for */
|
|
return ( OE_OK );
|
|
} /* end sci_select_not_exists */
|
|
|
|
int
|
|
sci_edit_files ( SCI_LIST sl, char * symbolic_name, char * config_str )
|
|
{
|
|
SCI_ELEM sl_elem;
|
|
struct stat st;
|
|
int i;
|
|
int fd;
|
|
const char *av[16];
|
|
char *rev_arg;
|
|
char rcs_file[MAXPATHLEN];
|
|
char *tempfile;
|
|
ERR_LOG log;
|
|
int status;
|
|
char tempslot [2];
|
|
char * selected_rev;
|
|
char * trunk_rev;
|
|
BOOLEAN defunct;
|
|
BOOLEAN is_link;
|
|
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* end if */
|
|
sl_elem = sci_first ( sl );
|
|
log = oxm_open ( &rcs_monitor, RCS_MONITOR );
|
|
while ( sl_elem != NULL ) {
|
|
check_path ( sl_elem -> name );
|
|
lstat ( sl_elem->name, &st );
|
|
is_link = ( st.st_mode & S_IFMT ) == S_IFLNK;
|
|
stat ( sl_elem->name, &st );
|
|
if ( (access (sl_elem->name, F_OK) == 0 ) &&
|
|
((st.st_mode & S_IWUSR) && ! is_link )) {
|
|
ui_print ( VWARN, "File %s is writeable.\n", sl_elem -> name );
|
|
ui_print ( VCONT, "No check out performed for this file.\n" );
|
|
} else if (src_ctl_file_exists (sl_elem->name, &log) != 0) {
|
|
ui_print (VALWAYS,
|
|
"File %s is not under source control.\n",
|
|
sl_elem->name);
|
|
sl_elem->exists = FALSE;
|
|
} else {
|
|
sl_elem->exists = TRUE;
|
|
/*
|
|
* remove temp file
|
|
*/
|
|
tmpfile_delete ( sl_elem->name );
|
|
|
|
/*
|
|
tail = tail_pathname (sl_elem->name);
|
|
*/
|
|
|
|
/* Set up for remote execution. */
|
|
concat (rcs_file, sizeof(rcs_file), sl_elem->name, ",v", NULL);
|
|
/*
|
|
src_ctl_lookup_revision ( sl_elem -> name, symbolic_name, revision,
|
|
&log );
|
|
*/
|
|
if ( sl_elem -> ver_user != NULL ) {
|
|
|
|
rev_arg = alloc_switch('r', sl_elem -> ver_user );
|
|
i = 0;
|
|
av[i++] = "-t2";
|
|
av[i++] = tempslot;
|
|
av[i++] = "co";
|
|
/*
|
|
av[i++] = "-l";
|
|
*/
|
|
av[i++] = "-q";
|
|
av[i++] = rev_arg;
|
|
|
|
tempslot [0] = '3';
|
|
tempslot [1] = '\0';
|
|
/* test if file is binary */
|
|
/*
|
|
if (strcmp(sci_get_comment_leader ( sl_elem->name ), "BIN")
|
|
== 0) {
|
|
av[i++] = "-ko";
|
|
tempslot [0] = '4';
|
|
}
|
|
*/
|
|
av[i++] = working_file_tail;
|
|
av[i++] = rcs_file;
|
|
log = oxm_runcmd ( rcs_monitor, i, av, tmpfile_base () );
|
|
log = oxm_endcmd( rcs_monitor, &status );
|
|
|
|
/* End of remote execution. */
|
|
|
|
/* Copy the file into the sandbox and make it writable. */
|
|
(void) unlink (sl_elem->name);
|
|
tempfile = tmpfile_name (sl_elem->name);
|
|
rename ( tempfile, sl_elem->name );
|
|
free (tempfile);
|
|
|
|
tmpfile_delete ( sl_elem->name );
|
|
} else {
|
|
|
|
sci_read_file ( sl_elem->name, config_str, &selected_rev,
|
|
&defunct, &log ) ;
|
|
|
|
if ( defunct ) {
|
|
/* FIXME: should not print here, should return in status */
|
|
ui_print ( VALWAYS, "'%s' is defunct, aborting check-out.\n",
|
|
sl_elem -> name );
|
|
sl_elem = sci_next ( sl_elem );
|
|
continue;
|
|
} /* if */
|
|
fd = tmpfile_create ( sl_elem->name );
|
|
tempfile = tmpfile_name (sl_elem->name);
|
|
copy_file (sl_elem->name, tempfile, TRUE );
|
|
free(tempfile);
|
|
|
|
trunk_revision ( selected_rev, &trunk_rev );
|
|
ui_print ( VDETAIL, "Creating branch for user from ancestor %s\n",
|
|
selected_rev );
|
|
src_ctl_create_branch ( sl_elem -> name, trunk_rev, symbolic_name,
|
|
selected_rev, NULL, &log );
|
|
set_insert ( );
|
|
free(trunk_rev);
|
|
free(selected_rev);
|
|
|
|
(void) close (fd);
|
|
|
|
tmpfile_delete ( sl_elem->name );
|
|
|
|
}
|
|
/* Leave a writable file in the sandbox. */
|
|
chmod (sl_elem->name, 0644);
|
|
ui_print ( VNORMAL , "%s\n", sl_elem -> name );
|
|
}
|
|
/* Select next element for processing. */
|
|
sl_elem = sci_next ( sl_elem );
|
|
}
|
|
log = oxm_close ( rcs_monitor );
|
|
return ( OK );
|
|
}
|
|
|
|
int
|
|
sci_set_comment_leader ( SCI_ELEM sci_ptr, char * leader )
|
|
{
|
|
int i;
|
|
const char *av[16];
|
|
char *leader_arg;
|
|
char rcs_file[MAXPATHLEN];
|
|
int status;
|
|
ERR_LOG log;
|
|
|
|
sci_ptr -> leader = strdup ( leader );
|
|
leader_arg = alloc_switch('c', leader );
|
|
concat ( rcs_file, sizeof(rcs_file), sci_ptr -> name, ",v", NULL );
|
|
i = 0;
|
|
av[i++] = "rcs";
|
|
av[i++] = "-q";
|
|
av[i++] = leader_arg;
|
|
if ( ! sci_has_log ( sci_ptr ) ) {
|
|
av[i++] = "-ko";
|
|
} else {
|
|
av[i++] = "-kkv";
|
|
} /* if */
|
|
av[i++] = rcs_file;
|
|
av[i] = NULL;
|
|
if ( ( log = oxm_runcmd ( rcs_monitor, i, av, NULL ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
if ( ( log = oxm_endcmd ( rcs_monitor, &status ) ) != OE_OK )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
return(status);
|
|
}
|
|
|
|
char *
|
|
alloc_comment_leader ( char * file, struct rcfile rc_info)
|
|
{
|
|
char dbuf[MAXPATHLEN], fbuf[MAXPATHLEN];
|
|
char pattern[PATH_LEN];
|
|
char leader[PATH_LEN];
|
|
char cmt[PATH_LEN];
|
|
char *str;
|
|
int more, i, status, j;
|
|
|
|
|
|
get_rc_value ("COMMENT_LEADERS", &str, &rc_info, FALSE);
|
|
if (str == NULL)
|
|
return( NULL );
|
|
else
|
|
strcpy (cmt, str);
|
|
pattern[0] = '\0';
|
|
leader[0]='\0';
|
|
path(file, dbuf, fbuf);
|
|
|
|
more = TRUE;
|
|
i = 0;
|
|
|
|
while (more == TRUE) {
|
|
/* Find the next set of parenthesis. */
|
|
for (; (cmt[i] != '(') && (cmt[i] != '\0'); i++);
|
|
|
|
/* If we've run out of comment leaders then return NULL */
|
|
if (cmt[i] == '\0')
|
|
break;
|
|
|
|
/* Extract the pattern, */
|
|
i++;
|
|
for (j = 0; (cmt[i] != ';') && (cmt[i] != '\0'); j++, i++) {
|
|
pattern[j] = cmt[i];
|
|
}
|
|
pattern[j] = '\0';
|
|
|
|
if (cmt[i] == '\0')
|
|
break;
|
|
|
|
/* Extract the comment leader. */
|
|
i++;
|
|
for (j = 0; (cmt[i] != ')') && (cmt[i] != '\0'); j++, i++) {
|
|
leader[j] = cmt[i];
|
|
}
|
|
leader[j] = '\0';
|
|
|
|
if (cmt[i] == '\0')
|
|
break;
|
|
|
|
status = gmatch (fbuf, pattern);
|
|
if (status == TRUE)
|
|
return (strdup(leader));
|
|
|
|
}
|
|
|
|
return ( NULL );
|
|
|
|
}
|
|
|
|
int
|
|
match_comment_leader (char * comment_leader, struct rcfile rc_info)
|
|
{
|
|
char pattern[PATH_LEN];
|
|
char leader[PATH_LEN];
|
|
char cmt[PATH_LEN];
|
|
char *str;
|
|
int more, i, j;
|
|
|
|
get_rc_value ("COMMENT_LEADERS", &str, &rc_info, FALSE);
|
|
if (str == NULL)
|
|
return(FALSE);
|
|
else
|
|
strcpy (cmt, str);
|
|
|
|
pattern[0] = '\0';
|
|
leader[0]='\0';
|
|
|
|
more = TRUE;
|
|
i = 0;
|
|
|
|
while (more == TRUE) {
|
|
/* Find the next set of parenthesis. */
|
|
for (; (cmt[i] != '(') && (cmt[i] != '\0'); i++);
|
|
|
|
/* If we've run out of comment leaders then return NONE */
|
|
if (cmt[i] == '\0')
|
|
break;
|
|
|
|
/* Extract the pattern, */
|
|
i++;
|
|
for (j = 0; (cmt[i] != ';') && (cmt[i] != '\0'); j++, i++) {
|
|
pattern[j] = cmt[i];
|
|
}
|
|
pattern[j] = '\0';
|
|
|
|
if (cmt[i] == '\0')
|
|
break;
|
|
|
|
/* Extract the comment leader. */
|
|
i++;
|
|
for (j = 0; (cmt[i] != ')') && (cmt[i] != '\0'); j++, i++) {
|
|
leader[j] = cmt[i];
|
|
}
|
|
leader[j] = '\0';
|
|
|
|
if (cmt[i] == '\0')
|
|
break;
|
|
|
|
if (strcmp( comment_leader, leader) == 0)
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
/* Routines for manipulating the ".BCSset-???" files in a sandbox */
|
|
|
|
char *
|
|
set_file_pathname (const char * setname)
|
|
{
|
|
char pathname[MAXPATHLEN];
|
|
(void) concat(pathname, sizeof(pathname), "./.BCSset-",
|
|
setname, NULL);
|
|
|
|
return (strdup (pathname));
|
|
}
|
|
|
|
char *
|
|
set_log_pathname (char * setname)
|
|
{
|
|
char pathname[MAXPATHLEN];
|
|
(void) concat(pathname, sizeof(pathname), "./.BCSlog-",
|
|
setname, NULL);
|
|
|
|
return (strdup (pathname));
|
|
}
|
|
|
|
char *
|
|
set_path_pathname (char * setname)
|
|
{
|
|
char pathname[MAXPATHLEN];
|
|
(void) concat(pathname, sizeof(pathname), "./.BCSpath-",
|
|
setname, NULL);
|
|
|
|
return (strdup (pathname));
|
|
}
|
|
|
|
int
|
|
set_exists (char * setname)
|
|
{
|
|
|
|
if (access(set_file_pathname(setname), R_OK) < 0)
|
|
return(FALSE);
|
|
else
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
int
|
|
set_create (char * setname)
|
|
{
|
|
int fd;
|
|
|
|
fd = open(set_file_pathname (setname), O_WRONLY|O_CREAT|O_EXCL, 0666);
|
|
|
|
return (fd);
|
|
}
|
|
|
|
void
|
|
set_delete ( char * setname )
|
|
{
|
|
char * pathname;
|
|
|
|
pathname = set_file_pathname (setname);
|
|
|
|
(void) unlink(pathname);
|
|
}
|
|
|
|
void
|
|
new_set_cleanup(char * setname)
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(set_file_pathname(setname), &st) == 0 && st.st_size > 0)
|
|
return;
|
|
if (unlink(set_file_pathname(setname)) == 0)
|
|
ui_print(VALWAYS,
|
|
"rm: removing %s\n", set_file_pathname(setname));
|
|
if (unlink(set_log_pathname(setname)) == 0)
|
|
ui_print(VALWAYS,
|
|
"rm: removing %s\n", set_log_pathname(setname));
|
|
if (unlink(set_path_pathname(setname)) == 0)
|
|
ui_print(VALWAYS,
|
|
"rm: removing %s\n", set_path_pathname(setname));
|
|
}
|
|
|
|
FILE *
|
|
set_fopen ( const char * setname, const char * file_access )
|
|
{
|
|
char * working_set_file;
|
|
FILE * inf;
|
|
|
|
working_set_file = set_file_pathname (setname);
|
|
|
|
inf = fopen(working_set_file, file_access);
|
|
|
|
if (inf == NULL)
|
|
ui_print (VALWAYS, "Unable to open set file %s\n",
|
|
working_set_file);
|
|
return (inf);
|
|
|
|
}
|
|
|
|
/* Maybe this should be simplified to "file_fread()". */
|
|
int
|
|
set_fread ( char line[], int maxlinelength, FILE * inf )
|
|
{
|
|
int cnt;
|
|
int linelength;
|
|
|
|
linelength = maxlinelength;
|
|
|
|
cnt = 0;
|
|
|
|
if (fgets(line, linelength, inf) == NULL) {
|
|
strcpy (line, "");
|
|
return (-1);
|
|
} else {
|
|
cnt = 0;
|
|
while (cnt < maxlinelength) {
|
|
if (line[cnt] == '\n') {
|
|
line[cnt] = '\0';
|
|
}
|
|
cnt++;
|
|
}
|
|
}
|
|
return (strlen(line));
|
|
}
|
|
|
|
int
|
|
new_set_insert(char * setname, char * pathname)
|
|
{
|
|
char tmp_setname[MAXPATHLEN];
|
|
FILE *inf,
|
|
*inf_tmp;
|
|
char buffer[MAXPATHLEN];
|
|
int found,
|
|
setname_inserted;
|
|
|
|
concat(tmp_setname, sizeof(tmp_setname), setname, ".tmp", NULL);
|
|
|
|
/* Initailize tmpfile */
|
|
set_delete (tmp_setname);
|
|
(void) close (set_create (tmp_setname));
|
|
|
|
if (set_exists(setname) == FALSE)
|
|
(void) close (set_create (setname));
|
|
|
|
if ((inf = set_fopen(setname, "r")) == NULL)
|
|
return(FALSE);
|
|
|
|
if ((inf_tmp = set_fopen(tmp_setname, "w")) == NULL) {
|
|
(void) fclose (inf);
|
|
return(FALSE);
|
|
}
|
|
|
|
found = FALSE;
|
|
setname_inserted = FALSE;
|
|
while (set_fread(buffer, sizeof(buffer), inf) != -1) {
|
|
if (setname_inserted == FALSE) {
|
|
if (strcmp (pathname, buffer) > 0) {
|
|
fputs (buffer, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
} else if (strcmp (pathname, buffer) < 0) {
|
|
fputs (pathname, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
fputs (buffer, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
setname_inserted = TRUE;
|
|
} else {
|
|
/* pathname is already in set. */
|
|
fputs (buffer, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
setname_inserted = TRUE;
|
|
}
|
|
} else {
|
|
fputs (buffer, inf_tmp);
|
|
}
|
|
}
|
|
if (setname_inserted == FALSE) {
|
|
/* Add the name to the end of the file. */
|
|
fputs (pathname, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
}
|
|
|
|
(void) fclose (inf);
|
|
(void) fclose (inf_tmp);
|
|
|
|
if (rename(set_file_pathname(tmp_setname),
|
|
set_file_pathname(setname)) < 0) {
|
|
ui_print(VALWAYS,
|
|
"5 rename %s to %s failed", set_file_pathname(tmp_setname),
|
|
set_file_pathname(setname));
|
|
(void) unlink(set_file_pathname(tmp_setname));
|
|
return(1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
int
|
|
set_remove(char * setname, char * pathname)
|
|
{
|
|
char tmp_setname[MAXPATHLEN];
|
|
char buffer[MAXPATHLEN];
|
|
FILE *inf,
|
|
*inf_tmp;
|
|
int lines_written,
|
|
setname_removed;
|
|
|
|
if (set_exists (setname) == FALSE) {
|
|
fprintf (stderr, "Set %s does not exist\n", setname);
|
|
return(1);
|
|
}
|
|
|
|
(void) concat(tmp_setname, sizeof(tmp_setname),
|
|
setname, ".tmp", NULL);
|
|
|
|
set_delete (tmp_setname);
|
|
(void) close (set_create(tmp_setname));
|
|
|
|
if ((inf = set_fopen(setname, "r")) == NULL)
|
|
return(FALSE);
|
|
|
|
if ((inf_tmp = set_fopen(tmp_setname, "w")) == NULL) {
|
|
(void) fclose (inf);
|
|
return(FALSE);
|
|
}
|
|
|
|
lines_written = 0;
|
|
setname_removed = FALSE;
|
|
while (set_fread(buffer, sizeof(buffer), inf) != -1) {
|
|
if (setname_removed == FALSE) {
|
|
if (strcmp (pathname, buffer) == 0) {
|
|
setname_removed = TRUE;
|
|
} else {
|
|
lines_written++;
|
|
fputs (buffer, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
}
|
|
} else {
|
|
lines_written++;
|
|
fputs (buffer, inf_tmp);
|
|
fputc ('\n', inf_tmp);
|
|
}
|
|
}
|
|
|
|
(void) fclose (inf);
|
|
(void) fclose (inf_tmp);
|
|
|
|
if (rename(set_file_pathname(tmp_setname),
|
|
set_file_pathname(setname)) < 0) {
|
|
ui_print(VALWAYS,
|
|
"6 rename %s to %s failed", set_file_pathname(tmp_setname),
|
|
set_file_pathname(setname));
|
|
(void) unlink(set_file_pathname(tmp_setname));
|
|
return(1);
|
|
}
|
|
|
|
if (lines_written == 0) {
|
|
/* Set file is empty, delete it */
|
|
new_set_cleanup (setname);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
set_lookup(char * setname, char * pathname)
|
|
{
|
|
char buffer[MAXPATHLEN];
|
|
FILE *inf;
|
|
int found;
|
|
|
|
|
|
if ((inf = fopen( BCSSET, "r" )) == NULL)
|
|
return(FALSE);
|
|
|
|
found = FALSE;
|
|
while (set_fread(buffer, sizeof(buffer), inf) != -1) {
|
|
if (strcmp( buffer, pathname ) == 0 )
|
|
found = TRUE;
|
|
}
|
|
|
|
fclose(inf);
|
|
return(found);
|
|
}
|
|
|
|
/* Temporary file routines */
|
|
|
|
STATIC
|
|
int
|
|
tmpfile_create ( char * pathname )
|
|
{
|
|
char * tempfile;
|
|
int fd;
|
|
|
|
tempfile = tmpfile_name (pathname);
|
|
|
|
(void) unlink(temp_working_file);
|
|
fd = open(tempfile, O_WRONLY|O_CREAT|O_EXCL, 0666);
|
|
|
|
free(tempfile);
|
|
return (fd);
|
|
}
|
|
|
|
STATIC
|
|
char *
|
|
tmpfile_name ( char * pathname )
|
|
{
|
|
char tempfile[MAXPATHLEN];
|
|
char *tail, *base;
|
|
|
|
tail = (char *) tail_pathname (pathname);
|
|
base = tmpfile_base();
|
|
concat ( tempfile, sizeof(tempfile), base, "/",
|
|
tail, NULL);
|
|
|
|
free(tail);
|
|
return ( strdup( tempfile ) );
|
|
}
|
|
|
|
STATIC
|
|
void
|
|
tmpfile_delete ( char * pathname )
|
|
{
|
|
char * tempfile;
|
|
|
|
tempfile = tmpfile_name (pathname);
|
|
|
|
(void) unlink(tempfile);
|
|
free(tempfile);
|
|
}
|
|
|
|
STATIC
|
|
char *
|
|
tmpfile_base (void)
|
|
{
|
|
|
|
return (BCSTEMP);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* FUNCTION sci_real_fast_lookup_user_rev_list
|
|
*
|
|
* Provide user revisions for each file in a given list and a given set
|
|
*/
|
|
int sci_real_fast_lookup_user_rev_list ( SCI_LIST sl , char * set_name ,
|
|
int * missing_revs )
|
|
{
|
|
int status, ret;
|
|
BOOLEAN keep_looping;
|
|
SCI_ELEM sci_ptr;
|
|
int pid, fd;
|
|
FILE *tempfile_in_fd;
|
|
char template_file [MAXPATHLEN];
|
|
char tempdir [MAXPATHLEN];
|
|
char tempfile_in [MAXPATHLEN];
|
|
char tempfile_out [MAXPATHLEN];
|
|
char file [MAXPATHLEN];
|
|
char dir [MAXPATHLEN];
|
|
char revision [MAXPATHLEN];
|
|
char buffer [MAXPATHLEN];
|
|
char *rev_sw, *file_sw;
|
|
FILE *tempfile_out_fd;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_real_fast_lookup_user_rev_list.\n" );
|
|
if ( ! confirm_alloc ( sl ) ) {
|
|
return ( ERROR );
|
|
}
|
|
/* end if */
|
|
status = OK;
|
|
* missing_revs = FALSE;
|
|
|
|
/* This routines dumps all filenames in the "sl" list to a temporary file.
|
|
'rcsstat' is executed with the temporaru file as input ("-f").
|
|
The output is directed to yet another temporary file. We
|
|
then step through the "sl" list and the output temporary file
|
|
looking to match filenames and update the "sl" elements with the
|
|
revision numbers returned from "rcsstat".
|
|
*/
|
|
|
|
getcwd (dir, sizeof(dir));
|
|
strcpy ( template_file, "#srvtmpXXXXXX" );
|
|
|
|
/* Set up directory for temporary files. */
|
|
opentemp ( template_file , tempdir);
|
|
concat (tempfile_out, sizeof(tempfile_out), dir, "/", tempdir, "/rcsstat_out", NULL);
|
|
concat (tempfile_in, sizeof(tempfile_in), dir, "/", tempdir, "/rcsstat_in", NULL);
|
|
|
|
/* Open "rcsstat" temporary output file. */
|
|
if ((fd = open(tempfile_out, O_WRONLY|O_TRUNC|O_CREAT, 0777)) < 0) {
|
|
return(ERROR);
|
|
}
|
|
|
|
|
|
/* Open and write to "rcsstat" temporary input file. */
|
|
tempfile_in_fd = fopen (tempfile_in, "w");
|
|
for (sci_ptr = sci_first(sl); sci_ptr != NULL;
|
|
sci_ptr = sci_next(sci_ptr) ) {
|
|
#ifdef notdef
|
|
if ( sci_ptr -> skip )
|
|
continue;
|
|
/* end if */
|
|
#endif
|
|
fprintf (tempfile_in_fd, "%s\n", sci_ptr->name);
|
|
}
|
|
fclose (tempfile_in_fd);
|
|
|
|
/* Allocate switches to pass to "rcsstat". */
|
|
rev_sw = alloc_switch ('r', set_name);
|
|
file_sw = alloc_switch ('f', tempfile_in);
|
|
|
|
/* Execute the rcsstat command. */
|
|
pid = fd_runcmd("rcsstat", NULL, TRUE, -1, fd,
|
|
"rcsstat", "-q", "-V", "-R", "-D", rev_sw, file_sw, NULL);
|
|
close(fd);
|
|
|
|
ret = endcmd(pid);
|
|
|
|
/* Open the output file and start sifting through the results. */
|
|
tempfile_out_fd = fopen (tempfile_out, "r");
|
|
if (fgets (buffer, sizeof(buffer), tempfile_out_fd) == NULL) {
|
|
return ( ERROR );
|
|
}
|
|
sscanf (buffer, "%s\t%s\n", file, revision);
|
|
|
|
|
|
file[strlen(file)-2] = '\0';
|
|
* missing_revs = FALSE;
|
|
keep_looping = TRUE;
|
|
for ( sci_ptr = sci_first(sl); (keep_looping == TRUE) &&
|
|
(sci_ptr != NULL); ) {
|
|
#ifdef notdef
|
|
if ( sci_ptr -> skip )
|
|
continue;
|
|
/* end if */
|
|
#endif
|
|
/* Compare an entry in the output file with entry in the "sl" list. */
|
|
if (strcmp (file, sci_ptr->name) == 0) {
|
|
/* The're identical, fill in the version number for this element. */
|
|
if ( strstr ( buffer, "(defunct)" ) != NULL ) {
|
|
ui_print ( VDEBUG, "version %s of file %s is defunct\n",
|
|
revision, file);
|
|
sci_ptr -> defunct = TRUE;
|
|
} else if ( sci_ptr -> defunct ) {
|
|
ui_print ( VFATAL, "Contradiction between sandbox state and\n" );
|
|
ui_print ( VCONT, "information in source control system\n" );
|
|
ui_print ( VCONT, "regarding defunct status\n" );
|
|
ui_print ( VCONT, "for file: '%s'\n", sci_ptr -> name );
|
|
status = ERROR;
|
|
}
|
|
sci_ptr->ver_user = strdup (revision);
|
|
if ( sci_ptr -> ver_user == NULL ) {
|
|
ui_print ( VFATAL, "strdup of ver_user failed\n" );
|
|
status = ERROR;
|
|
break;
|
|
}
|
|
sci_ptr= sci_next(sci_ptr);
|
|
if (fgets (buffer, sizeof(buffer), tempfile_out_fd) != NULL) {
|
|
sscanf (buffer, "%s\t%s\n", file, revision);
|
|
file[strlen(file)-2] = '\0';
|
|
} else {
|
|
keep_looping = FALSE;
|
|
}
|
|
} else if (strcmp (file, sci_ptr->name) > 0) {
|
|
/* The "sl" list and the rcsstat output file are out of sync */
|
|
/* This is probably due to a file not having a revision to match
|
|
the revision string (i.e. the file doesn't have that revision).
|
|
Skip this element in the "sl" list. */
|
|
sci_ptr->ver_user = NULL;
|
|
* missing_revs = TRUE;
|
|
sci_ptr = sci_next(sci_ptr);
|
|
ui_print (VWARN, "Revision information on file %s is not available.\n",
|
|
sci_ptr->name);
|
|
status = ERROR;
|
|
} else {
|
|
/* Somehow, rcsstat returned more entries then it should. skipt them */
|
|
if (fgets (buffer, sizeof(buffer), tempfile_out_fd) != NULL) {
|
|
sscanf (buffer, "%s\t%s\n", file, revision);
|
|
file[strlen(file)-2] = '\0';
|
|
} else {
|
|
keep_looping = FALSE;
|
|
}
|
|
ui_print (VWARN, "Revision information '%s' was unexpected.\n",
|
|
file);
|
|
status = ERROR;
|
|
}
|
|
|
|
} /* end for */
|
|
fclose (tempfile_out_fd);
|
|
unlink (tempfile_out);
|
|
unlink (tempfile_in);
|
|
rmdir (tempdir);
|
|
|
|
ui_print ( VDEBUG, "Leaving sci_real_fast_lookup_user_rev_list.\n" );
|
|
return ( status );
|
|
} /* sci_real_fast_lookup_user_rev_list */
|
|
|
|
/*
|
|
* FUNCTION sci_real_fast_lookup_latest_rev_list
|
|
*
|
|
* Provide user revisions for each file in a given list and a given set
|
|
*/
|
|
int
|
|
sci_real_fast_lookup_latest_rev_list ( SCI_LIST sl , char * set_name ,
|
|
int * missing_revs )
|
|
{
|
|
int status = OK, ret;
|
|
BOOLEAN keep_looping;
|
|
SCI_ELEM sci_ptr;
|
|
int pid, fd;
|
|
FILE *tempfile_in_fd;
|
|
char template_file [MAXPATHLEN];
|
|
char tempdir [MAXPATHLEN];
|
|
char tempfile_in [MAXPATHLEN];
|
|
char tempfile_out [MAXPATHLEN];
|
|
char file [MAXPATHLEN];
|
|
char revision [MAXPATHLEN];
|
|
char buffer [MAXPATHLEN];
|
|
char *rev_sw, *file_sw;
|
|
FILE *tempfile_out_fd;
|
|
char dir [MAXPATHLEN];
|
|
BOOLEAN all_defunct = TRUE;
|
|
|
|
ui_print ( VDEBUG, "Entering sci_real_fast_lookup_latest_rev_list.\n" );
|
|
if ( ! confirm_alloc ( sl ) )
|
|
return ( ERROR );
|
|
/* if */
|
|
|
|
/* Open temporary file. */
|
|
strcpy ( template_file, "#srvtmpXXXXXX" );
|
|
getcwd (dir, sizeof(dir));
|
|
opentemp ( template_file , tempdir);
|
|
concat (tempfile_out, sizeof(tempfile_out), dir, "/", tempdir, "/rcsstat_out", NULL);
|
|
concat (tempfile_in, sizeof(tempfile_in), dir, "/", tempdir, "/rcsstat_in", NULL);
|
|
if ((fd = open(tempfile_out, O_WRONLY|O_TRUNC|O_CREAT, 0777)) < 0) {
|
|
return (ERROR);
|
|
}
|
|
|
|
tempfile_in_fd = fopen (tempfile_in, "w");
|
|
for ( sci_ptr = sl -> head; sci_ptr != NULL; sci_ptr = sci_next(sci_ptr)) {
|
|
if ( sci_ptr -> defunct )
|
|
continue;
|
|
all_defunct = FALSE;
|
|
fprintf (tempfile_in_fd, "%s\n", sci_ptr->name);
|
|
}
|
|
fclose (tempfile_in_fd);
|
|
|
|
if ( all_defunct ) {
|
|
unlink (tempfile_in);
|
|
rmdir (tempdir);
|
|
return ( OK );
|
|
} /* if */
|
|
rev_sw = alloc_switch ('r', set_name);
|
|
file_sw = alloc_switch ('f', tempfile_in);
|
|
|
|
pid = fd_runcmd("rcsstat", NULL, TRUE, -1, fd,
|
|
"rcsstat", "-q", "-V", "-R", rev_sw, file_sw, NULL);
|
|
close(fd);
|
|
|
|
ret = endcmd(pid);
|
|
tempfile_out_fd = fopen (tempfile_out, "r");
|
|
if (fgets (buffer, sizeof(buffer), tempfile_out_fd) == NULL)
|
|
return (ERROR);
|
|
sscanf (buffer, "%s\t%s\n", file, revision);
|
|
file[strlen(file)-2] = '\0';
|
|
* missing_revs = FALSE;
|
|
keep_looping = TRUE;
|
|
for ( sci_ptr = sci_first ( sl );
|
|
(keep_looping == TRUE) && (sci_ptr != NULL); ) {
|
|
if ( sci_ptr -> defunct ) {
|
|
sci_ptr= sci_next(sci_ptr);
|
|
continue;
|
|
} /* if */
|
|
if (strcmp (file, sci_ptr->name) == 0) {
|
|
sci_ptr->ver_latest = strdup (revision);
|
|
if ( sci_ptr -> ver_latest == NULL ) {
|
|
ui_print ( VFATAL, "strdup of sci_ptr -> ver_latest failed.\n" );
|
|
status = ERROR;
|
|
break;
|
|
}
|
|
sci_ptr= sci_next(sci_ptr);
|
|
if (fgets (buffer, sizeof(buffer), tempfile_out_fd) != NULL) {
|
|
sscanf (buffer, "%s\t%s\n", file, revision);
|
|
file[strlen(file)-2] = '\0';
|
|
} else {
|
|
keep_looping = FALSE;
|
|
}
|
|
} else if (strcmp (file, sci_ptr->name) > 0) {
|
|
/* The "sl" list and the rcsstat output file are out of sync */
|
|
/* This is probably due to a file not having a revision to match
|
|
the revision string (i.e. the file doesn't have that revision).
|
|
Skip this element in the "sl" list. */
|
|
sci_ptr->ver_latest = NULL;
|
|
* missing_revs = TRUE;
|
|
sci_ptr = sci_next(sci_ptr);
|
|
status = ERROR;
|
|
} else {
|
|
if (fgets (buffer, sizeof(buffer), tempfile_out_fd) != NULL) {
|
|
sscanf (buffer, "%s\t%s\n", file, revision);
|
|
file[strlen(file)-2] = '\0';
|
|
} else {
|
|
keep_looping = FALSE;
|
|
}
|
|
status = ERROR;
|
|
}
|
|
}
|
|
fclose (tempfile_out_fd);
|
|
unlink (tempfile_out);
|
|
unlink (tempfile_in);
|
|
rmdir (tempdir);
|
|
|
|
ui_print ( VDEBUG, "Leaving sci_real_fast_lookup_latest_rev_list.\n" );
|
|
return ( status );
|
|
} /* sci_real_fast_lookup_latest_rev_list */
|