高质量C++/C编程指南-第1章-文件结构
第1章 文件结构 每个C++/C程序通常分为两个文件。一个文件用于保存程序的声明( declaration ),称为头文件。另一个文件用于保存程序的实现( implementation ),称为定义( definition )文件。
C++/C 程序的头文件以“ .h ”为后缀, C 程序的定义文件以“ .c ”为后缀, C++ 程序的定义文件通常以“ .cpp ”为后缀(也有一些系统以“ .cc ”或“ .cxx ”为后缀)。
1.1 版权和版本的声明 版权和版本的声明位于头文件和定义文件的开头(参见示例 1-1 ),主要内容有:
( 1 )版权信息。
( 2 )文件名称,标识符,摘要。
( 3 )当前版本号,作者 / 修改者,完成日期。
( 4 )版本历史信息。
/*
* Copyright (c) 2001,上海贝尔有限公司网络应用事业部
* All rights reserved.
*
* 文件名称: filename.h
* 文件标识: 见配置管理计划书
* 摘 要: 简要描述本文件的内容
*
* 当前版本: 1.1
* 作 者: 输入作者(或修改者)名字
* 完成日期: 2001年7月20日
*
* 取代版本 : 1.0
* 原作者 : 输入原作者(或修改者)名字
* 完成日期: 2001年5月10日
*/
示例 1-1 版权和版本的声明
1.2 头文件的结构 头文件由三部分内容组成:
( 1 )头文件开头处的版权和版本声明(参见示例 1-1 )。
( 2 )预处理块。
( 3 )函数和类结构声明等。
假设头文件名称为 graphics.h,头文件的结构参 见示例 1-2 。
l 【规则 1-2-1 】 为了防止头文件被重复引用,应当用 ifndef/define/endif 结构产生预处理块。
l 【规则 1-2-2 】 用 #include < filename.h> 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。
l 【规则 1-2-3 】 用 #include “filename.h” 格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。
2 【建议 1-2-1 】 头文件中只存放“声明”而不存放“定义”
在 C++ 语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。这虽然会带来书写上的方便,但却造成了风格不一致,弊大于利。建议将成员函数的定义与声明分开,不论该函数体有多么小。
2 【建议 1-2-2 】 不提倡使用全局变量,尽量不要在头文件中出现象 extern int value 这类声明。
// 版权和版本声明见示例 1-1 ,此处省略。
#ifndef GRAPHICS_H // 防止 graphics.h 被重复引用
#define GRAPHICS_H
#include <math.h> // 引用标准库的头文件
…
#include “myheader.h” // 引用非标准库的头文件
…
void Function1(…); // 全局函数声明
…
class Box // 类结构声明
{
…
};
#endif
示例 1-2 C++/C头文件的结构
1.3 定义文件的结构 定义文件有三部分内容:
(1) 定义文件开头处的版权和版本声明(参见示例 1-1 )。
(2) 对一些头文件的引用。
(3) 程序的实现体(包括数据和代码)。
假设定义文件的名称为 graphics.cpp, 定义 文件的结构参 见示例 1-3 。
// 版权和版本声明见示例 1-1 ,此处省略。
#include “graphics.h” // 引用头文件
…
// 全局函数的实现体
void Function1(…)
{
…
}
// 类成员函数的实现体
void Box::Draw(…)
{
…
}
示例 1-3 C++/C定义文件的结构
1.4 头文件的作用 早期的编程语言如 Basic 、 Fortran 没有头文件的概念, C++/C 语言的初学者虽然会用使用头文件,但常常不明其理。这里对头文件的作用略作解释:
( 1 )通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。
( 2 )头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。
1.5 目录结构 如果一个软件的头文件数目比较多(如超过十个),通常应将头文件和定义文件分别保存于不同的目录,以便于维护。
例如可将头文件保存于 include 目录,将定义文件保存于 source 目录(可以是多级目录)。
如果某些头文件是私有的,它不会被用户的程序直接引用,则没有必要公开其“声明”。为了加强信息隐藏,这些私有的头文件可以和定义文件存放于同一个目录。
ldapconf.h
/*
**++
** MODULE: $RCSfile$
** $Revision: 83122 $
** $Date: 2011-07-12 00:58:50 -0700 (Tue, 12 Jul 2011) $
**
** DESCRIPTION:
**
** ENVIRONMENT: Generic Server (NT/Unix)
**
** COPYRIGHT: Copyright ?2004 TIBCO Software Inc.
**
** MODIFICATION HISTORY:
**
** $Log$
** Revision 7.5 2006/07/21 14:07:51 cdurrant
** CR19009_1 - support UTF-8 attribute value translation in LDAP
**
** Revision 7.4 2004/11/23 14:32:41Z CharlesD
** pod_1194_reint - LDAP referrals CRs reintegration
** Revision 7.3 2004/11/04 17:13:44Z JohnCA
** LDAP GENERALI reint
** Revision 7.2.1.4 2004/10/21 15:49:17Z JohnCA
** Revision 7.2.1.3 2004/10/21 09:08:56Z JohnCA
** LDAP DN format Enhancements
** Revision 7.2.1.2 2004/09/28 16:29:20Z JohnCA
** LDAP Enhancements for Generali
** Revision 7.2.1.1 2002/01/09 13:03:46Z JohnCA
** Duplicate revision
** Revision 7.2 2002/01/09 13:03:46Z SteveC
** Automatically reintegrated (by autreint.ksh):
** Reintegration from REINT_630 1.141.1.4
** Revision 7.1.2.2 2002/01/07 15:01:13 SteveC
** Revision 7.1.2.1 2001/03/09 18:54:28 SteveC
** Duplicate revision
** Revision 1.8 2001/03/09 08:58:03 nick
** Automated code tidying
** Revision 1.7 2001/03/08 10:49:41 nick
** Auto dead code removal
** Revision 1.6 1998/01/14 17:31:06 ben
** Revision 1.5 1998/01/05 11:35:07 ben
** Revision 1.4 1997/12/10 09:59:12 ben
** UNIX was complaining about weird EOF character.
** No chg other than resave
** Revision 1.3 1997/12/09 08:18:06 steve
** Use message file to hold output messages
** Revision 1.2 1997/11/25 18:10:37 ben
**--
*/
#include "ldapconf.i"
/* CR6685 SAC 08-12-97 : Definitions for messages */
#define M_EXISTS 1
#define M_DELETED 2
#define M_NOT_FOUND 3
#define M_E_CFG_READ 4
#define M_E_LOGIN 5
#define M_E_PASSWD_MAT 6
#define M_PASSWD_CONF 7
#define M_ONLY_SWADMIN 8
#define M_E_INVALID_ENTRY 9
#define M_ASK_HOST 10
#define M_ASK_PORTNUMBER 11
#define M_E_PORTNO 12
#define M_ASK_BIND_NAME 13
#define M_ASK_START_SEARCH 14
#define M_ASK_FILTER_SEARCH 15
#define M_E_NO_ENTRIES 16
#define M_VAL_CHANGE 17
#define M_VAL_CHG_TO 18
#define M_E_DUPLICATE 19
#define M_VAL_DELETE 20
#define M_VAL_ADD 21
#define M_ASK_USERNAME 22
#define M_ASK_ROLE 23
#define M_ASK_GROUP 24
#define M_ASK_MENUNAME 25
#define M_ASK_DESCRIPTION 26
#define M_ASK_LANGUAGE 27
#define M_ASK_SORTMAIL 28
#define M_ASK_ENTER 29
#define M_CONNECTION 30
#define M_HOSTNAME 31
#define M_PORTNO 32
#define M_CREDENTIALS 33
#define M_PASSWORD 34
#define M_SEARCH 35
#define M_BASE 36
#define M_FILTER 37
#define M_USERNAME 38
#define M_MENUNAME 39
#define M_LANGUAGE 40
#define M_DESCRIPTION 41
#define M_SORTMAIL 42
#define M_GROUPUSERS 43
#define M_ROLEUSER 44
#define M_EXTRA 45
#define M_DIT 46
#define M_ASK_ENTER_X 47
#define M_OVERWRITE 48
#define M_E_FILENAME 49
#define M_CONN_TESTING 50
#define M_CONN_SUCCESS 51
#define M_ENTRIES_FOUND 52
#define M_ENTRIES_NONE 53
#define M_ASK_INFO_FILE 54
#define M_NO_DATA_CHANGED 55
#define M_E_DATA_WRITE 56
#define M_DATA_SAVED 57
#define M_M_CONN_INFO 58
#define M_M_SEARCH_INFO 59
#define M_M_ATTRIB_MAP 60
#define M_M_VIEW_INFO 61
#define M_M_CONN_TEST 62
#define M_M_RETURN_DIT 63
#define M_M_SAVE 64
#define M_M_SYNCHRONISE 65
#define M_M_QUIT 66
#define M_M_ENTER_OPTION 67
#define M_E_INVALID_OPTION 68
#define M_E_UNKNOWN_OPTION 69
#define M_E_SUBOPTION_REQ 70
#define M_E_UNKNOWN_SUBOPTION 71
#define M_E_VALUE_REQ 72
#define M_DOWNLOAD_USER 73
#define M_MAPPING 74
#define M_FILE_SCREEN 75
#define M_STAFFW_NOT_EXTRA 76
#define M_X500_NOT_EXTRA 77
#define M_ASK_CHG_PASSWD 78
#define M_ASK_PASSWD 79
#define M_EXTRA_MENU 80
#define M_MULTIPLE_MAP 81
#define M_MAPPINGS 82
#define M_ASK_SAVE 83
#define M_PLEASE_SAVE 84
#define M_AMBIGUOUS 85
#define M_FULL_PARTIAL_QUIT 86
#define M_CONNECT_FAIL 87
#define M_SETINFO_FAIL 88
#define M_ERROR_PARAM 89
/* CR9574 New messages for additional QSUPERVISOR & userflags parameter */
#define M_ASK_QSUPERVISORS 90
#define M_QSUPERVISORS 91
#define M_ASK_USERFLAGS 92
#define M_USERFLAGS 93
/* CR9574 End */
/* CR16174 JMC 30-9-2004: New messages for GROUPNAME and ROLENAME parameter */
#define M_ASK_GROUPNAME 94
#define M_GROUPNAME 95
#define M_ASK_ROLENAME 96
#define M_ROLENAME 97
/* CR16174 End */
/* CR16395 JMC 15-9-2004: New message for GRPMEMLDAP */
#define M_M_GRPMEM_LDAP 98
#define M_GRPUSERS 99
/* CR16395 End */
/* CR14734 CJED 22-NOV-2004 - reintegrated */
#define M_PARTIAL_FOUND 100
/*
** CR19009 - CJED 21-JUL-2006 - messages for attribute UTF-8 translation
*/
#define M_M_ENABLE_AV_TRANS 101
#define M_M_DISABLE_AV_TRANS 102
/*
** MR 38043 - LingWu 11-Dec-2008 - messages for attribute DN pattern
*/
#define M_ASK_DN_PATTERN 103
#define M_DNPATTERN 104
#define M_ASK_ENABLE_SSL 105
#define M_ASK_DISABLE_SSL 106
#define M_ASK_CERT_PATH 107
#define M_ASK_ACTIVE_DIRECT 108
#define M_VAL_ADD_X500 109
ldapcon.c
/*
**++
** MODULE: $RCSfile$
** $Revision: 83122 $
** $Date: 2011-07-12 00:58:50 -0700 (Tue, 12 Jul 2011) $
**
** DESCRIPTION:
**
** ENVIRONMENT: Generic Server (NT/Unix)
**
** COPYRIGHT: Copyright ?2004, TIBCO Software Inc.
**
** MODIFICATION HISTORY:
**
** $Log$
** Revision 7.51 2007/02/14 11:13:47 mbanfiel
** CR19771 Re-order output of mappings to match input order
**
** Revision 7.50 2007/02/12 16:54:00Z cdurrant
** CR19761 - report group membership errors to file as well as screen
** Revision 7.49 2007/02/01 19:44:50Z stevec
** CR19716: If LDAP attribute that determines type of entry comes after membership attribute then members aren't checked
** Revision 7.48 2007/02/01 12:03:49Z stevec
** CR19716: If LDAP attribute that determines type of entry comes after membership attribute then members aren't checked
** Revision 7.47 2006/12/18 11:28:48Z cdurrant
** CR19501 - fail MOVESYSINFO if LDAP sync fails
** Revision 7.46 2006/12/15 12:21:01Z cdurrant
** CR19495 - fix groupusers list handling
** Revision 7.45 2006/12/08 11:38:22Z cdurrant
** CR19493_1 - fix error on Win32 build
** Revision 7.44 2006/12/07 12:02:26Z cdurrant
** CR19493 - show the value of GROUPUSERS attribute in ldapconf
** Revision 7.42 2006/08/03 14:02:43Z rhudson
** CR19048 Itanium Build
** Revision 7.41 2006/07/21 14:07:50Z cdurrant
** CR19009_1 - support UTF-8 attribute value translation in LDAP
** Revision 7.40 2006/07/14 06:49:35Z SteveC
** CR18964: LDAPCONF test treats spaces as valid users in group member lists
** Revision 7.39 2006/06/21 14:47:05Z SteveC
** CR18828: CR18665 was broken by Charles' change to ldapconf.c
** Revision 7.38 2006/05/19 10:21:24Z cdurrant
** CJED_fix_UNIX_build - min macro not available on UNIX build, also used correct size for lustrncpy function.
** Revision 7.37 2006/05/18 16:15:41Z SteveC
** CR18665: Ldapconf outputs error when member of group doesn't exist, even though they may appear later in the LDAP search results
** Revision 7.36 2006/01/30 15:35:01Z mbanfiel
** CR17995: LDAP truncates group membership list at 100 characters
** Revision 7.35 2006/01/30 11:57:16Z mbanfiel
** CR17344 Add ldap_check_all_members_valid function
** Revision 7.34 2006/01/06 09:38:36Z rhudson
** CR17052 Main Trunk Reint
** Revision 7.33 2005/11/14 17:20:12Z rhudson
** Revision 7.32 2005/06/06 09:26:19Z mbanfiel
** CR17172 Product name change
** Revision 7.31 2005/03/14 17:02:54Z njpatel
** Reintegration of CR16829
** CR14758 Corrected overlooked reintegration.
** Revision 7.30 2005/03/08 16:57:32Z jcarver
** Fix for ldap debug trace
** Revision 7.29 2005/02/21 16:28:44Z nhaines
** Changed copyright info
** Revision 7.28 2005/01/28 14:21:07Z RobertH
** CR16881 Fixed startup when server not running
** Revision 7.27 2005/01/25 15:46:37Z CharlesD
** CR16732_1 - First attempt at swldap file upgrade
** Revision 7.26 2005/01/21 12:49:22Z JohnCA
** Fix for ldapconf seg fault
** Revision 7.25 2005/01/20 17:30:53Z JohnCA
** Fixes in line with BG for CR16847
** Revision 7.24 2005/01/07 11:04:14Z NickH
** Modified copyright notice to match spec
** Revision 7.23 2004/12/22 15:11:57Z JohnCA
** Fix for GroupUsers in LDAP
** Revision 7.22 2004/12/16 15:21:34Z JohnCA
** Fix for valid MEMBERLIST in ldap
** Revision 7.21 2004/12/15 13:32:53Z JohnCA
** ldapconf TEST -l fix
** Revision 7.20 2004/12/10 08:59:05Z NickH
** Removed debug printf
** Revision 7.19 2004/12/10 08:53:55Z NickH
** Added new copyright system
** Revision 7.18 2004/12/02 15:49:56Z JohnCA
** Partial Sync to LDAP MSActive
** Revision 7.17 2004/11/23 14:32:40Z CharlesD
** pod_1194_reint - LDAP referrals CRs reintegration
** Revision 7.16 2004/11/08 17:33:03Z JohnCA
** Change X.500 to LDAP
** Revision 7.15 2004/11/05 10:09:01Z JohnCA
** Copyright
** Revision 7.14 2004/11/04 15:13:22Z JohnCA
** LDAP GENERALI reint
** Revision 7.12.1.6 2004/11/02 16:11:23Z JohnCA
** Fix array overrun in ldapconf
** Revision 7.12.1.5 2004/10/21 16:38:11Z JohnCA
** CR16296: Copyright TIBCO 2004
** Revision 7.12.1.4 2004/10/21 15:49:02Z JohnCA
** Revision 7.12.1.3 2004/10/21 09:07:54Z JohnCA
** LDAP DN format Enhancements
** Revision 7.12.1.2 2004/09/28 16:27:49Z JohnCA
** LDAP Enhancements for Generali
** Revision 7.12.1.1 2004/09/13 13:39:41Z JohnCA
** Duplicate revision
** Revision 7.12 2004/09/13 13:39:41Z CharlesD
** CR15884_reint_MT - reintegrated back into /batch trunk for POD/1218
** Revision 7.11 2004/09/10 12:59:02Z RobertH
** CR16288 Linux - Remove {} round each field as it is not valid
** Revision 7.10 2004/02/10 16:34:39Z KevinG
** CR14973 copyright changes
** Revision 7.9 2003/08/14 14:02:11Z SidA
** Reintegrations from i9.2-o(1.0.2), i9.2-o(2.2.1), i9.2-o(2.2.2),
** i9.2-o(3.1) amd i9.2-o(3.3) into main trunk
** Revision 7.8 2003/04/16 13:19:08 KevinG
** CR13267 Update copyright
** Revision 7.7 2002/07/15 15:26:26 SteveC
** CR11968 : Using extra attributes for ldap X.500 can cause ldapconf and the BG process to crash.
** Revision 7.6 2002/06/14 09:52:28 SteveC
** CR11680: copyright version update
** Revision 7.5.1.2 2003/08/06 11:13:45 JohnCA
** Reint plus LDAP fixes
** Revision 7.5.1.1 2002/01/14 14:07:44 JohnCA
** Duplicate revision
** Revision 7.5 2002/01/14 14:07:44 SteveC
** CR10933: NT port integration
** Revision 7.4 2002/01/09 13:03:44 SteveC
** Automatically reintegrated (by autreint.ksh):
** Reintegration from REINT_630 1.141.1.4
** Revision 7.3.2.3 2002/01/07 15:01:12 SteveC
** Revision 7.3.2.2 2002/01/03 11:57:17 SteveC
** Integration from 1.101 --> 1.101.1.27 (PART I)
** Revision 7.3.2.1 2001/11/16 13:51:39 SteveC
** Duplicate revision
** Revision 7.2 2001/07/16 08:51:14 SteveC
** Reintegration from FILPACKDB branch:
**
** 1.103 --> 1.103.4.4
** Revision 7.1 2001/03/09 18:54:19 nick
** Version number update
** Revision 1.32 2001/03/09 08:57:55 nick
** Automated code tidying
** Revision 1.31 2001/03/08 10:49:33 nick
** Auto dead code removal
** Revision 1.30 2000/05/25 21:31:44 markb
** CLEAN_BUILD - Post POD/STR/201 & POD/CUS/146 Integ.
** Revision 1.29 2000/05/23 00:37:15 markb
** POD_STR_201_Phase_2_Reint_Main - Reintegrating POD_STR_201 Phase 2 into the main trunk.
** Revision 1.28 2000/03/23 14:37:42 kevin
** CR8897 Stop GPF in ldapconf
** Revision 1.27.1.2 2000/04/11 17:02:43 keith
** CR8937: Fix compiler warning on AIX
** Revision 1.27.1.1 2000/03/08 13:15:37 keith
** Duplicate revision
** Revision 1.27 2000/03/08 13:15:37 ben
** CR8892 - oversize attribute values cause coredumping in x500
** mode reporting.
** CR8893 - do not destroy swldaplck file if you are not the originator.
** Revision 1.26 2000/01/10 09:50:17 steve
** Integration from 1.40.1.11 --> 1.40.1.16 and changes for CR8272
** Revision 1.25 1999/10/13 16:21:24 markb
** POD_STR_013 - Added new swprim password checking stuff.
** Revision 1.24 1999/09/21 15:06:09 markb
** POD/STR/013 - Changed BOOL to SWBOOL.
** Revision 1.23 1999/07/01 14:45:26 sid
** POD/STR/011 - pick up correct prototypes for sw_ref_msg
** Revision 1.22 1999/05/21 10:09:23 steve
** Revision 1.21 1999/05/18 07:06:56 steve
** Revision 1.20 1999/04/21 13:46:06 steve
** Re-integration from 1.32.1.9
** Revision 1.19 1999/01/28 17:17:16 steve
** Automatically reintegrated (by autreint.ksh):
** Re-integration from I249_NTServer_MultiNode (1.32.1.4)
** Revision 1.18.1.2 1998/12/22 13:38:24 steve
** CR7869 : modify search filter the same way the Staffware BG does
** Revision 1.18.1.1 1998/10/05 06:43:52 steve
** Duplicate revision
** Revision 1.17 1998/07/22 10:33:12 ian
** I265 - Server Integration: compiler warnings
** Revision 1.16 1998/07/17 15:53:26 keith
** CR7284: changes for clean compile on UNIX
** Revision 1.15 1998/06/26 14:07:13 ian
** CR7036 - FIL Re-integration
** Revision 1.14.1.2 1998/05/29 10:53:44 ian
** CR7036 - FIL Integration
** Revision 1.14.1.1 1998/02/09 10:56:54 ian
** Duplicate revision
** Revision 1.13.1.2 1998/01/28 17:09:17 steve
** CR6733 : Changes made for NT SAL SDK
** Revision 1.12 1998/01/05 11:35:06 ben
** Revision 1.11 1997/12/11 10:55:02 ben
** allow entry of NULL to signify ""
** Revision 1.10 1997/12/10 12:19:43 steve
** Revision 1.9 1997/12/10 10:44:25 ben
** for a clean UNIX build
** Revision 1.8 1997/12/09 08:18:02 steve
** Use message file to hold output messages
** Revision 1.7 1997/12/08 14:38:06 ben
** Revision 1.6 1997/11/28 19:10:39 ben
** Safeguard changes
** Revision 1.5 1997/11/26 18:56:36 ben
** Revision 1.4 1997/11/25 17:58:00 ben
** if len extras too long won't get assigned
** Revision 1.3 1997/11/25 11:09:53 ben
** Revision 1.2 1997/11/24 10:03:42 ben
** Revision 1.1 1997/11/24 09:50:01 ben
** Initial revision
**--
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef SW4_UNIX
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#endif
#include "swvers.h"
#include "swtype.h"
#include "swldap.h"
#include "sallogin.h"
#include "filpost.h"
#include "sallinit.h"
#include "postutil.i"
#include "postwrit.i"
#include "errhand.h" /* CR6685 SAC */
#include "errhand.i" /* CR6685 SAC */
#include "wchar.h"
#include "sallogin.i"
#include "filnode.i"
#include "swprim.i"
#include "filuser.i"
#include "swchrset.i"
#include "internal.h" /* CR6733 SAC */
/* CR10765 SAC 15-11-01 */
#include "psulmain.h"
#include "filpattr.h"
#include "mbset.h"
#ifdef SW4_WIN32SERVER
#include <conio.h>
#endif
/* CR10647 Fix all compiler warnings cause I'm nice (probably cause more problems though) */
/* Needs an include file at some point (defined in filinit2.c) */
EXTERNAL int create_filsh (LPCHR swdir, LPCHR debug_log, LPCHR registry_area);
/* SID POD/STR/011 - message funcs now def'd correctly in unimsg.i */
#include "unimsg.i"
#define SIZEOFBIGP 16
#define ER_ENTRY_NOTFOUND -1
#define LINESONSCR 24
/* CR14758 NJP 14Mar05 - #ifdef left out during reintegration */
#ifdef SW4_UNIX
/* CR14758 JMC 25-2-04 */
extern int ldap_debug;
#endif
NODE my_node;
UCHR msg[256];
UCHR lockfile[256]; /* must be global for sighandler to pick up */
SW_LDAP_info *sw_ldap_info, *sw_ldap_info_copy = NULL;
SW_LDAP *ldap;
SWINT32 ret;
SWINT32 num_entries;
SWINT32 filsh;
/* CR10765 SAC 15-11-01 */
PATTR_SH hPAT;
/* CR6685 SAC 08-12-97 : message session handle */
int msg_sh;
int lock_fh;
/* CR16288 Linux - Remove {} round each field as it is not valid */
const char *bigentries[] = {
"ATTRIB",
"CONNECT",
"SEARCH",
"TEST",
"HELP",
"VIEW",
"MOVESYSINFO"
};
typedef struct
{
UCHR BIGP[SIZEOFBIGP];
UCHR member[10];
int set;
} ENTRY;
ENTRY entries[] = {
{"ATTRIB", "u",}, /* Username */
{"ATTRIB", "r",}, /* Role */
{"ATTRIB", "g",}, /* Group */
{"ATTRIB", "menu",},
{"ATTRIB", "desc",}, /* Description */
{"ATTRIB", "lang",}, /* Language */
{"ATTRIB", "sort",}, /* Sortmail */
{"ATTRIB", "x",}, /* Extras */
{"CONNECT", "h",}, /* Hostname */
{"CONNECT", "port",}, /* Username */
{"CONNECT", "dn",}, /* DN Entry */
{"CONNECT", "pwd",}, /* Password */
{"SEARCH", "dn",},
{"SEARCH", "s",}, /* Search filter */
{"TEST", "f",}, /* File name */
{"TEST", "s",}, /* user/role/group/attribute info to be downloaded from LDAP DIT. */
{"TEST", "l",},
{"MOVESYSINFO", "full",},
{"MOVESYSINFO", "partial"}
};
/* CR9574 Now uses NUM_SW_ELEMENTS in swldap.h instead of */
/* hardcoded sizes */
X500_TO_SWARE_MAP xsmap[NUM_SW_ELEMENTS];
typedef struct ll
{
UCHR x500[SW_LDAP_ATTRNAME_SIZE];
UCHR staffware[SW_LDAP_ATTRNAME_SIZE];
struct ll *next;
}
LL;
#include "ldapconf.h"
LL *head = NULL;
#ifdef __cplusplus
extern "C"
{
#endif
int g_UTF8Support = 0;
#ifdef __cplusplus
}
#endif
/*
**++
** FUNCTIONs LL_xxx perform the required operations for maintaining a linked list of character strings
**--
*/
PRIVATE LL *LL_find (LPUCHR srch)
{
UCHR usrch[256];
UCHR ucurr[256];
LL *p = head;
LL *ret = NULL;
lustrcpy (usrch, srch);
ucase (usrch);
for (p = head; p != NULL; p = p->next)
{
lustrcpy (ucurr, p->staffware);
ucase (ucurr);
if (!lustrcmpul (ucurr, usrch))
{
ret = p;
break;
}
}
return ret;
}
/*
**++
**
**--
*/
PRIVATE void LL_add (LPUCHR staffware, LPUCHR x500)
{
LL *p = NULL;
LL *next;
int x;
p = LL_find (staffware);
if (p)
{
printf (SW_REF_MSG (M_EXISTS), staffware); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
return;
}
/* CR9574 Now uses NUM_SW_ELEMENTS in swldap.h instead of */
/* hardcoded sizes */
for(x=0;x<NUM_SW_ELEMENTS;x++)
{
if (!lustrcmpul (staffware, xsmap[x].staffware))
{
printf (SW_REF_MSG (M_STAFFW_NOT_EXTRA)); /* CR6685 SAC */
printf ("\n"); /* CR6685 */
return;
}
if (!lustrcmpul (staffware, xsmap[x].x500))
{
printf (SW_REF_MSG (M_X500_NOT_EXTRA)); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
return;
}
}
next = (LL *) malloc (sizeof (LL));
if (head != NULL)
for (p = head; p->next != NULL; p = p->next); /* traverse to end of list */
else
head = next; /* anchor the head */
lustrcpy (next->staffware, staffware);
lustrcpy (next->x500, x500);
next->next = NULL;
if (p)
p->next = next;
}
/*
**++
**
**--
*/
PRIVATE void LL_del (LPUCHR val)
{
LL *p = NULL, *prev = NULL;
for (p = head; p != NULL; prev = p, p = p->next)
{
if (!lustrcmpul (p->staffware, val))
{
if (prev)
prev->next = p->next;
else /* top of the list, so reset head! */
head = p->next;
free (p);
printf (SW_REF_MSG (M_DELETED), val); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
return;
}
}
printf (SW_REF_MSG (M_NOT_FOUND), val); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
return;
}
/*
**++
**
**--
*/
PRIVATE void LL_chg (LPUCHR old, LPUCHR nw)
{
LL *o;
LL *n;
o = LL_find (old);
if (!o)
{
printf (SW_REF_MSG (M_NOT_FOUND), old); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
return;
}
n = LL_find (nw);
if (n)
{
printf (SW_REF_MSG (M_EXISTS), nw); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
return;
}
/* got here so continue */
lustrcpy (o->x500, nw);
}
/*
**++
**
**--
*/
PRIVATE void LL_list ()
{
LL *p;
int lineno = 0;
for (p = head; p != NULL; p = p->next)
{
printf ("%s -> %s\n", p->staffware, p->x500);
lineno++;
if (lineno > (LINESONSCR - 2))
{
prompt ();
lineno = 0;
}
}
}
/*
**++
**
**--
*/
PRIVATE void LL_freeall ()
{
LL *p, *next;
for (p = head; p != NULL; p = next)
{
next = p->next;
free (p);
}
head = NULL;
}
/*
**++
** FUNCTION ucase
**
** DESCRIPTION :
** Converts a given character string to upper case
**--
*/
PRIVATE void ucase (LPUCHR str)
{
if (!str)
return;
while (*str)
{
*str = toupper (*str);
str++;
}
}
/*
**++
** FUNCTION lcase
**
** DESCRIPTION :
** Converts a given character string to lower case
**--
*/
PRIVATE void lcase (LPUCHR str)
{
if (!str)
return;
while (*str)
{
*str = tolower (*str);
str++;
}
}
/*
**++
** REQD?
**--
*/
PRIVATE void initialise (void)
{
int c;
int numents;
numents = sizeof (entries) / sizeof (entries[0]);
for (c = 0; c < numents; c++)
{
entries[c].set = 0;
}
}
/*
**++
** RENAME
**--
*/
PRIVATE void getbigentry (LPUCHR BIGP, LPUCHR * entry)
/* return an error */
{
int c;
int numents = (sizeof (bigentries)) / sizeof (bigentries[0]);
for (c = 0; (c < numents); c++)
if (!lustrcmp (bigentries[c], BIGP))
{
*entry = (LPUCHR) bigentries[c];
break;
}
}
/*
**++
** RENAME
**--
*/
PRIVATE int getentry (LPUCHR BIGP, LPUCHR member)
{
int c;
int numents;
int ret = ER_ENTRY_NOTFOUND;
numents = sizeof (entries) / sizeof (entries[0]);
for (c = 0; ((ret == ER_ENTRY_NOTFOUND) && (c < numents)); c++)
{
if ((!lustrcmp (entries[c].BIGP, BIGP))
&& (!lustrcmp (entries[c].member, member)))
ret = c;
}
return ret;
}
/*
**++
** FUNCTION GetValidCh
**
** DESCRIPTION :
** Displays a prompt for an input character; this character is checked to be a valid character for the context
**--
*/
PRIVATE void GetValidCh (char *prompt, char *valid, LPUCHR str)
{
UCHR buff[80];
UCHR promptcpy[128];
lustrcpy (promptcpy, prompt);
while (TRUE)
{
printf ("%s", promptcpy);
gets ((char *) buff);
ucase (buff);
if ((strstr (valid, (char *) buff) == NULL)
|| lustrlen (buff) != 1)
{
printf (SW_REF_MSG (M_E_INVALID_ENTRY)); /* CR6685 SAC */
printf ("\n\n"); /* CR6685 SAC */
}
else
break;
}
lustrcpy (str, buff);
}
/*
**++
** FUNCTION connection
**
** DESCRIPTION :
** Read connection information
**--
*/
PRIVATE void connection ()
{
UCHR buff[1024];
printf (SW_REF_MSG (M_ASK_HOST), sw_ldap_info->hostname); /* CR6685 SAC */
/* MR 41741: Check for buffer overruns
if (strlen (gets ((char *) buff)))
lustrcpy (sw_ldap_info->hostname, buff);
*/
my_gets (sw_ldap_info->hostname, sizeof(sw_ldap_info->hostname)-1);
while (TRUE)
{
int i;
UCHR b[10];
printf (SW_REF_MSG (M_ASK_PORTNUMBER), sw_ldap_info->hostname, sw_ldap_info->portno); /* CR6685 SAC */
if (!strlen (gets ((char *) buff)))
break;
i = atoi ((char *) buff);
sprintf ((char *) b, "%d", i);
if ((i < 0) || lustrcmp (buff, b))
{
printf (SW_REF_MSG (M_E_PORTNO)); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
}
else
{
sw_ldap_info->portno = i;
break;
}
}
printf (SW_REF_MSG (M_ASK_BIND_NAME), sw_ldap_info->credentials); /* CR6685 SAC */
my_gets (sw_ldap_info->credentials, SW_LDAP_CRED_SIZE);
GetValidCh (SW_REF_MSG (M_ASK_CHG_PASSWD), "YN", buff); /* CR6685 SAC */
if (!lustrcmp (buff, "Y"))
{
int ret = SW_OK;
UCHR Msg1[100], Msg2[100];
lustrcpy (Msg1, SW_REF_MSG (M_ASK_PASSWD));
lustrcpy (Msg2, SW_REF_MSG (M_PASSWD_CONF));
/*
** Use new swprim function for getting and confirming password entry
*/
do
{
ret =
sw_get_password_confirm (buff, Msg1, Msg2,
sizeof (buff) - 1);
if (ret != SW_OK)
{
printf ("%s\n", SW_REF_MSG (M_E_PASSWD_MAT));
}
}
while (ret != SW_OK);
lustrcpy (sw_ldap_info->password, buff);
}
printf (SW_REF_MSG (M_ASK_ACTIVE_DIRECT), sw_ldap_info->isAD ? "Yes" : "No");
GetValidCh("","YN",buff);
sw_ldap_info->isAD =!lustrcmp (buff, "Y");
#ifndef SW4_WIN32SERVER
if(sw_ldap_info->enableSSL)
{
GetValidCh(SW_REF_MSG(M_ASK_DISABLE_SSL),"YN",buff);
sw_ldap_info->enableSSL =lustrcmp (buff, "Y");
}
else
{
GetValidCh(SW_REF_MSG(M_ASK_ENABLE_SSL),"YN",buff);
sw_ldap_info->enableSSL =!lustrcmp (buff, "Y");
}
if(sw_ldap_info->enableSSL)
{
printf (SW_REF_MSG (M_ASK_CERT_PATH), sw_ldap_info->certpath); /* CR6685 SAC */
my_gets (sw_ldap_info->certpath, SW_LDAP_BASE_SIZE);
}
#endif
}
/*
**++
** FUNCTION search
**
** DESCRIPTION :
** Read search information
**--
*/
PRIVATE void search ()
{
/* MR 41741 UCHR buff[256]; */
printf (SW_REF_MSG (M_ASK_START_SEARCH), sw_ldap_info->base); /* CR6685 SAC */
/* MR 41741: Check for buffer overruns
* if (strlen (gets ((char *) buff)))
* lustrcpy (sw_ldap_info->base, buff);
*/
my_gets (sw_ldap_info->base, sizeof(sw_ldap_info->base)-1);
printf (SW_REF_MSG (M_ASK_FILTER_SEARCH), sw_ldap_info->filter); /* CR6685 SAC */
/* MR 41741: Check for buffer overruns
* if (strlen (gets ((char *) buff)))
* lustrcpy (sw_ldap_info->filter, buff);
*/
my_gets (sw_ldap_info->filter, sizeof(sw_ldap_info->filter)-1);
printf (SW_REF_MSG (M_ASK_DN_PATTERN), sw_ldap_info->dnPattern); /* CR6685 SAC */
/* MR 41741: Check for buffer overruns
* if (strlen (gets ((char *) buff)))
* {
* lustrcpy (sw_ldap_info->dnPattern, buff);
* }
*/
my_gets (sw_ldap_info->dnPattern, sizeof(sw_ldap_info->dnPattern)-1);
}
/*
**++
**
**--
*/
PRIVATE void extra_to_LL ()
{
int x;
LL_freeall (); /* to be sure, to be sure */
for (x = 0; x < sw_ldap_info->num_extras; x++)
LL_add (sw_ldap_info->extra[x]->staffware, sw_ldap_info->extra[x]->x500);
}
/*
**++
**
**--
*/
PRIVATE void LL_to_extra ()
{
LL *p;
SW_LDAP_extra_free (sw_ldap_info);
for (p = head; p != NULL; p = p->next)
{
SW_LDAP_extra_add (sw_ldap_info, p->staffware, p->x500);
}
}
/*
**++
** FUNCTION extras
**
** DESCRIPTION :
** Read extra information
**--
*/
PRIVATE void extras ()
{
UCHR buff[SW_LDAP_ATTRNAME_SIZE];
extra_to_LL ();
while (TRUE)
{
GetValidCh (SW_REF_MSG (M_EXTRA_MENU), "LCDAQ", buff); /* CR6685 SAC */
if ((!head) && strstr ("LCD", (char *) buff))
{ /*attempted to list/change/delete an empty list */
printf (SW_REF_MSG (M_E_NO_ENTRIES)); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
continue;
}
if (!lustrcmp (buff, "L"))
LL_list ();
else if (!lustrcmp (buff, "C"))
{
LL *o, *n;
UCHR nw[256];
printf (SW_REF_MSG (M_VAL_CHANGE)); /* CR6685 SAC */
gets ((char *) buff);
if (!*buff)
continue;
o = LL_find (buff);
if (!o)
{
printf (SW_REF_MSG (M_NOT_FOUND), buff); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
continue;
}
printf (SW_REF_MSG (M_VAL_CHG_TO), buff); /* CR6685 SAC */
gets ((char *) nw);
/* CR9620 Don't allow values to be changed to NULL or space (cause PAG are bound */
/* to try a space prefix) or something equally silly */
if(*nw == 0 || *nw == ' ') {
/* print out a message that it's invalid */
printf (SW_REF_MSG (M_E_INVALID_ENTRY));
printf("\n");
} else {
n = LL_find (nw);
if (n)
{
printf (SW_REF_MSG (M_EXISTS), nw); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
continue;
}
LL_chg (buff, nw);
/* CR9620 End */
}
}
else if (!lustrcmp (buff, "D"))
{
printf (SW_REF_MSG (M_VAL_DELETE)); /* CR6685 SAC */
gets ((char *) buff);
if (!*buff)
continue;
LL_del (buff);
}
else if (!lustrcmp (buff, "A"))
{
UCHR x500[SW_LDAP_ATTRNAME_SIZE];
printf (SW_REF_MSG (M_VAL_ADD)); /* CR6685 SAC */
gets ((char *) buff);
if (!*buff)
continue;
printf (SW_REF_MSG (M_VAL_ADD_X500));
gets ((char *) x500);
/* CR13995 JMC 31-7-03 Don't allow values to be added to NULL or space */
if(*buff == 0 || *buff == ' ' || *x500 == 0 || *x500 == ' ') {
/* print out a message that it's invalid */
printf (SW_REF_MSG (M_E_INVALID_ENTRY));
printf("\n");
} else {
/* add entry to extras */
LL_add (buff, x500);
} /* CR13995 end */
}
else if (!lustrcmp (buff, "Q"))
{
LL_to_extra ();
return;
}
}
}
/*
**++
** FUNCTION chk_dups
**
** DESCRIPTION :
** Check no duplicates in attribute settings
**--
*/
PRIVATE SWBOOL chk_dups ()
{
struct DUPCHECK
{
UCHR x500[SW_LDAP_ATTRNAME_SIZE + 1];
int count;
} dupcheck[7];
int x, y;
SWBOOL are_dups = FALSE;
memset ((LPCHR) & dupcheck, '\0', sizeof (dupcheck));
for (x = 0; x < 7; x++)
{
for (y = 0; y < 7; y++)
{
if (!lustrcmpul (xsmap[x].x500, (LPUCHR) ""))
break;
if (!lustrcmpul (xsmap[x].x500, dupcheck[y].x500))
{ /* match found */
dupcheck[y].count++;
break;
}
}
if (y >= 7)
{ /* not found */
y = 0;
while (lustrcmp (dupcheck[y].x500, (LPUCHR) ""))
y++;
lustrcpy (dupcheck[y].x500, xsmap[x].x500);
dupcheck[y].count++;
}
}
for (x = 0; x < 7; x++)
{
if (dupcheck[x].count > 1)
{
printf (SW_REF_MSG (M_MULTIPLE_MAP),
dupcheck[x].count, dupcheck[x].x500); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
are_dups = TRUE;
}
}
return are_dups;
}
/*
**++
** FUNCTION my_gets
**
** DESCRIPTION :
**
**--
*/
PRIVATE void my_gets (LPUCHR entry, int size)
{
UCHR buff[2048]; /* MR 41741 : Cope with long responses */
int len;
len = strlen(gets((char *)buff));
if (len)
{
/* CR16486 JMC 2-11-2004: fix array overrun */
lustrncpy (entry, buff, size);
}
}
/*
**++
** FUNCTION attrib
**
** DESCRIPTION :
** Read attribute mapping information
**--
*/
PRIVATE void attrib ()
{
printf (SW_REF_MSG (M_ASK_USERNAME), sw_ldap_info->username); /* CR6685 SAC */
my_gets (sw_ldap_info->username, SW_LDAP_ATTRNAME_SIZE);
/* CR16174 JMC 30-9-2004: Add new mappings for groupname and rolename */
printf(SW_REF_MSG(M_ASK_GROUPNAME), sw_ldap_info->groupname);
my_gets(sw_ldap_info->groupname, SW_LDAP_ATTRNAME_SIZE);
printf(SW_REF_MSG(M_ASK_ROLENAME), sw_ldap_info->rolename);
my_gets(sw_ldap_info->rolename, SW_LDAP_ATTRNAME_SIZE);
/* CR16174 End */
printf (SW_REF_MSG (M_ASK_DESCRIPTION), sw_ldap_info->description); /* CR6685 SAC */
my_gets (sw_ldap_info->description, SW_LDAP_ATTRNAME_SIZE);
printf (SW_REF_MSG (M_ASK_LANGUAGE), sw_ldap_info->language); /* CR6685 SAC */
my_gets (sw_ldap_info->language, SW_LDAP_ATTRNAME_SIZE);
printf (SW_REF_MSG (M_ASK_MENUNAME), sw_ldap_info->menuname); /* CR6685 SAC */
my_gets (sw_ldap_info->menuname, SW_LDAP_ATTRNAME_SIZE);
printf (SW_REF_MSG (M_ASK_SORTMAIL), sw_ldap_info->sortmail); /* CR6685 SAC */
my_gets (sw_ldap_info->sortmail, SW_LDAP_SORTMAIL_SIZE);
printf (SW_REF_MSG (M_ASK_GROUP), sw_ldap_info->groupusers); /* CR6685 SAC */
my_gets (sw_ldap_info->groupusers, SW_LDAP_ATTRNAME_SIZE);
printf (SW_REF_MSG (M_ASK_ROLE), sw_ldap_info->roleuser); /* CR6685 SAC */
my_gets (sw_ldap_info->roleuser, SW_LDAP_ATTRNAME_SIZE);
/* CR9574 Added new mapping for qsupervisors and userflags entry */
printf (SW_REF_MSG (M_ASK_QSUPERVISORS), sw_ldap_info->qsupervisors);
my_gets(sw_ldap_info->qsupervisors, SW_LDAP_ATTRNAME_SIZE);
printf (SW_REF_MSG (M_ASK_USERFLAGS), sw_ldap_info->userflags);
my_gets(sw_ldap_info->userflags, SW_LDAP_ATTRNAME_SIZE);
/* CR9574 End */
extras ();
SW_LDAP_set_def_mappings (filsh, (X500_TO_SWARE_MAP *) xsmap,
sw_ldap_info);
if (chk_dups ())
prompt ();
}
/*
**++
**
**--
*/
PRIVATE void prompt ()
{
printf (SW_REF_MSG (M_ASK_ENTER)); /* CR6738 ZJS */
getchar ();
}
/*
**++
**
**--
*/
PRIVATE void view (int interactive)
{
int x;
int lineno;
int len;
UCHR buff[SW_LDAP_PASSWD_SIZE];
if (interactive)
printf ("\n\n\n\n\n\n");
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_DIT),
sw_ldap_info->whichdit ? "LDAP" : "Staffware"); /* CR6685 SAC */
printf("\n");
printf (SW_REF_MSG (M_GRPUSERS),
sw_ldap_info->grpmemldap ? "LDAP DN" : "MEMBER LIST"); /* CR16395 JMC */
printf ("\n\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_CONNECTION)); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_HOSTNAME), sw_ldap_info->hostname); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_PORTNO), sw_ldap_info->portno); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_CREDENTIALS), sw_ldap_info->credentials); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
memset (&buff, '\0', sizeof (buff));
len = lustrlen (sw_ldap_info->password);
for (x = 0; x < len; x++)
buff[x] = '*';
printf (SW_REF_MSG (M_PASSWORD), buff); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_SEARCH)); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_BASE), sw_ldap_info->base); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_FILTER), sw_ldap_info->filter); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_DNPATTERN), sw_ldap_info->dnPattern); /* MR 38043 LingWu */
printf ("\n"); /* MR 38043 LingWu */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_MAPPINGS)); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_USERNAME), sw_ldap_info->username); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
/* CR16174 JMC 30-9-2004: Add view for groupname and rolename */
printf(SW_REF_MSG(M_GROUPNAME), sw_ldap_info->groupname);
printf("\n");
printf(SW_REF_MSG(M_ROLENAME), sw_ldap_info->rolename);
printf("\n");
/* CR16174 End */
/* CR19771 MEB 14Feb07 Display in same order as input of mappings */
printf (SW_REF_MSG (M_DESCRIPTION), sw_ldap_info->description); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
/* CR19771 MEB 14Feb07 Display in same order as input of mappings */
printf (SW_REF_MSG (M_LANGUAGE), sw_ldap_info->language); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_MENUNAME), sw_ldap_info->menuname); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_SORTMAIL), sw_ldap_info->sortmail); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_GROUPUSERS), sw_ldap_info->groupusers); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
printf (SW_REF_MSG (M_ROLEUSER), sw_ldap_info->roleuser); /* CR6685 SAC */
printf ("\n"); /* CR6685 SAC */
/* CR9574 Added view of qsupervisors and userflags */
printf (SW_REF_MSG (M_QSUPERVISORS), sw_ldap_info->qsupervisors);
printf ("\n");
printf (SW_REF_MSG (M_USERFLAGS), sw_ldap_info->userflags);
printf ("\n");
/* CR9574 End */
printf ("\n\n\n");
if (interactive)
{
int y;
prompt ();
for (y = 0; y < LINESONSCR; y++)
printf ("\n");
}
lineno = 0;
for (x = 0; x < sw_ldap_info->num_extras; x++)
{
printf (SW_REF_MSG (M_EXTRA), x + 1, sw_ldap_info->extra[x]->staffware, sw_ldap_info->extra[x]->x500); /* CR6685 SAC */
printf ("\n"); /* CR6685