~noskcaj/ubuntu/saucy/xinetd/2.3.15

« back to all changes in this revision

Viewing changes to xinetd/sconf.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Seyrat
  • Date: 2004-04-18 13:33:57 UTC
  • Revision ID: james.westby@ubuntu.com-20040418133357-czeqeju37433xvdd
Tags: upstream-2.3.13
ImportĀ upstreamĀ versionĀ 2.3.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (c) Copyright 1992 by Panagiotis Tsirigotis
 
3
 * (c) Sections Copyright 1998-2001 by Rob Braun
 
4
 * All rights reserved.  The file named COPYRIGHT specifies the terms 
 
5
 * and conditions for redistribution.
 
6
 */
 
7
 
 
8
#include "config.h"
 
9
#ifdef HAVE_NETDB_H
 
10
#include <netdb.h>
 
11
#endif
 
12
 
 
13
#include "str.h"
 
14
#include "sio.h"
 
15
#include "sconf.h"
 
16
#include "timex.h"
 
17
#include "addr.h"
 
18
#include "nvlists.h"
 
19
 
 
20
 
 
21
#define NEW_SCONF()               NEW( struct service_config )
 
22
#define FREE_SCONF( scp )         FREE( scp )
 
23
 
 
24
/*
 
25
 * Conditional free; checks if the pointer is NULL
 
26
 */
 
27
#define COND_FREE( x )           if ( x )                   \
 
28
                                 {                          \
 
29
                                    *x = NUL ;              \
 
30
                                    free( (char *) x ) ;    \
 
31
                                 }
 
32
 
 
33
 
 
34
/*
 
35
 * Allocate a new service_config and initialize the service name field
 
36
 * with 'name'; the rest of the fields are set to 0 which gives them
 
37
 * their default values.
 
38
 */
 
39
struct service_config *sc_alloc( const char *name )
 
40
{
 
41
   struct service_config *scp ;
 
42
   const char *func = "sc_alloc" ;
 
43
 
 
44
   scp = NEW_SCONF() ;
 
45
   if ( scp == NULL )
 
46
   {
 
47
      out_of_memory( func ) ;
 
48
      return( NULL ) ;
 
49
   }
 
50
   CLEAR( *scp ) ;
 
51
   SC_NAME(scp) = new_string( name ) ;
 
52
   return( scp ) ;
 
53
}
 
54
 
 
55
 
 
56
static void release_string_pset( pset_h pset )
 
57
{
 
58
   pset_apply( pset, free, NULL ) ;
 
59
   pset_destroy( pset ) ;
 
60
}
 
61
 
 
62
 
 
63
/*
 
64
 * Free all malloc'ed memory for the specified service
 
65
 */
 
66
void sc_free( struct service_config *scp )
 
67
{
 
68
#ifdef HAVE_DNSREGISTRATION
 
69
   COND_FREE( SC_MDNS_NAME(scp) );
 
70
#endif
 
71
   COND_FREE( SC_NAME(scp) ) ;
 
72
   COND_FREE( SC_ID(scp) ) ;
 
73
   COND_FREE( SC_PROTONAME(scp) ) ;
 
74
   COND_FREE( SC_SERVER(scp) ) ;
 
75
   COND_FREE( (char *)SC_REDIR_ADDR(scp) ) ;
 
76
   COND_FREE( (char *)SC_BIND_ADDR(scp) ) ;
 
77
   COND_FREE( (char *)SC_ORIG_BIND_ADDR(scp) ) ;
 
78
   COND_FREE( (char *)SC_BANNER(scp) ) ;
 
79
   COND_FREE( (char *)SC_BANNER_SUCCESS(scp) ) ;
 
80
   COND_FREE( (char *)SC_BANNER_FAIL(scp) ) ;
 
81
   if ( SC_SERVER_ARGV(scp) )
 
82
   {
 
83
      char **pp ;
 
84
 
 
85
      /*
 
86
       * argv[ 0 ] is a special case because it may not have been allocated yet
 
87
       */
 
88
      if ( SC_SERVER_ARGV(scp)[ 0 ] != NULL)
 
89
         free( SC_SERVER_ARGV(scp)[ 0 ] ) ;
 
90
      for ( pp = &SC_SERVER_ARGV(scp)[ 1 ] ; *pp != NULL ; pp++ )
 
91
         free( *pp ) ;
 
92
      free( (char *) SC_SERVER_ARGV(scp) ) ;
 
93
   }
 
94
   COND_FREE( LOG_GET_FILELOG( SC_LOG( scp ) )->fl_filename ) ;
 
95
 
 
96
   if ( SC_ACCESS_TIMES(scp) != NULL )
 
97
   {
 
98
      ti_free( SC_ACCESS_TIMES(scp) ) ;
 
99
      pset_destroy( SC_ACCESS_TIMES(scp) ) ;
 
100
   }
 
101
 
 
102
   if ( SC_ONLY_FROM(scp) != NULL )
 
103
   {
 
104
      addrlist_free( SC_ONLY_FROM(scp) ) ;
 
105
      pset_destroy( SC_ONLY_FROM(scp) ) ;
 
106
   }
 
107
 
 
108
   if ( SC_NO_ACCESS(scp) != NULL )
 
109
   {
 
110
      addrlist_free( SC_NO_ACCESS(scp) ) ;
 
111
      pset_destroy( SC_NO_ACCESS(scp) ) ;
 
112
   }
 
113
 
 
114
   if ( SC_ENV_VAR_DEFS(scp) != NULL )
 
115
      release_string_pset( SC_ENV_VAR_DEFS(scp) ) ;
 
116
   if ( SC_PASS_ENV_VARS(scp) != NULL )
 
117
      release_string_pset( SC_PASS_ENV_VARS(scp) ) ;
 
118
   if ( SC_ENV( scp )->env_type == CUSTOM_ENV && 
 
119
                                    SC_ENV( scp )->env_handle != ENV_NULL )
 
120
      env_destroy( SC_ENV( scp )->env_handle ) ;
 
121
   if (SC_DISABLED(scp) ) 
 
122
      release_string_pset( SC_DISABLED(scp) ) ;
 
123
   if (SC_ENABLED(scp) ) 
 
124
      release_string_pset( SC_ENABLED(scp) ) ;
 
125
   
 
126
   CLEAR( *scp ) ;
 
127
   FREE_SCONF( scp ) ;
 
128
}
 
129
 
 
130
 
 
131
/*
 
132
 * Create a configuration for one of the special services
 
133
 */
 
134
struct service_config *sc_make_special( const char *service_name, 
 
135
                                        const builtin_s *bp, 
 
136
                                        int instances )
 
137
{
 
138
   struct service_config *scp ;
 
139
   const char *func = "sc_make" ;
 
140
 
 
141
   if ( ( scp = sc_alloc( service_name ) ) == NULL )
 
142
      return( NULL ) ;
 
143
 
 
144
   SC_ID(scp) = new_string( SC_NAME(scp) ) ;
 
145
   if ( SC_ID(scp) == NULL )
 
146
   {
 
147
      out_of_memory( func ) ;
 
148
      return( NULL ) ;
 
149
   }
 
150
   SC_SPECIFY( scp, A_ID ) ;
 
151
 
 
152
   /*
 
153
    * All special services are internal
 
154
    */
 
155
   M_SET( SC_TYPE(scp), ST_SPECIAL ) ;
 
156
   M_SET( SC_TYPE(scp), ST_INTERNAL ) ;
 
157
   SC_BUILTIN(scp) = bp ;
 
158
   SC_SPECIFY( scp, A_TYPE ) ;
 
159
 
 
160
   M_SET( SC_XFLAGS(scp), SF_NORETRY ) ;
 
161
   SC_SPECIFY( scp, A_FLAGS ) ;
 
162
 
 
163
   SC_INSTANCES(scp) = instances ;
 
164
   SC_SPECIFY( scp, A_INSTANCES ) ;
 
165
 
 
166
   SC_WAIT(scp) = NO ;
 
167
   SC_SPECIFY( scp, A_WAIT ) ;
 
168
 
 
169
   return( scp ) ;
 
170
}
 
171
 
 
172
 
 
173
static void dump_log_data( int fd, struct service_config *scp, int tab_level )
 
174
{
 
175
   struct log *lp = SC_LOG( scp ) ;
 
176
   struct filelog *flp ;
 
177
   int i ;
 
178
 
 
179
   switch ( LOG_GET_TYPE( lp ) )
 
180
   {
 
181
      case L_NONE:
 
182
         tabprint( fd, tab_level, "No logging\n" ) ;
 
183
         return ;
 
184
 
 
185
      case L_COMMON_FILE:
 
186
         tabprint( fd, tab_level, "Logging to common log file\n" ) ;
 
187
         break ;
 
188
 
 
189
      case L_FILE:
 
190
         flp = LOG_GET_FILELOG( lp ) ;
 
191
         tabprint( fd, tab_level, "Logging to file: %s", flp->fl_filename ) ;
 
192
 
 
193
         if ( FILELOG_SIZE_CONTROL( flp ) )
 
194
            Sprint( fd, " (soft=%d hard=%d)\n",
 
195
                        flp->fl_soft_limit, flp->fl_hard_limit ) ;
 
196
         else
 
197
            Sprint( fd, " (no limits)\n" ) ;
 
198
         break ;
 
199
      
 
200
      case L_SYSLOG:
 
201
         tabprint( fd, tab_level,
 
202
            "Logging to syslog. Facility = %s, level = %s\n",
 
203
               nv_get_name( syslog_facilities, lp->l_sl.sl_facility ),
 
204
               nv_get_name( syslog_levels, lp->l_sl.sl_level ) ) ;
 
205
         break ;
 
206
   }
 
207
 
 
208
   tabprint( fd, tab_level, "Log_on_success flags =" ) ;
 
209
   for ( i = 0 ; success_log_options[ i ].name != NULL ; i++ )
 
210
      if ( M_IS_SET( SC_LOG_ON_SUCCESS(scp), success_log_options[ i ].value ) )
 
211
         Sprint( fd, " %s", success_log_options[ i ].name ) ;
 
212
   Sputchar( fd, '\n' ) ;
 
213
 
 
214
   tabprint( fd, tab_level, "Log_on_failure flags =" ) ;
 
215
   for ( i = 0 ; failure_log_options[ i ].name != NULL ; i++ )
 
216
      if ( M_IS_SET( SC_LOG_ON_FAILURE(scp), failure_log_options[ i ].value ) )
 
217
         Sprint( fd, " %s", failure_log_options[ i ].name ) ;
 
218
   Sputchar( fd, '\n' ) ;
 
219
}
 
220
 
 
221
 
 
222
/*
 
223
 * Print info about service scp to file descriptor fd
 
224
 */
 
225
void sc_dump( struct service_config *scp, 
 
226
              int fd, 
 
227
              int tab_level, 
 
228
              bool_int is_defaults )
 
229
{
 
230
   const struct name_value    *nvp ;
 
231
   unsigned             u ;
 
232
   char                 **pp ;
 
233
 
 
234
   if ( is_defaults )
 
235
      tabprint( fd, tab_level, "Service defaults\n" ) ;
 
236
   else
 
237
      tabprint( fd, tab_level, "Service configuration: %s\n", SC_NAME(scp) ) ;
 
238
 
 
239
   if ( ! is_defaults )
 
240
   {
 
241
      tabprint( fd, tab_level+1, "id = %s\n", SC_ID(scp) ) ;
 
242
 
 
243
      if ( ! M_ARE_ALL_CLEAR( SC_XFLAGS(scp) ) )
 
244
      {
 
245
         tabprint( fd, tab_level+1, "flags =" ) ;
 
246
         for ( nvp = &service_flags[ 0 ] ; nvp->name != NULL ; nvp++ )
 
247
            if ( M_IS_SET( SC_XFLAGS(scp), nvp->value ) )
 
248
               Sprint( fd, " %s", nvp->name ) ;
 
249
         Sputchar( fd, '\n' ) ;
 
250
      }
 
251
 
 
252
      if ( ! M_ARE_ALL_CLEAR( SC_TYPE(scp) ) )
 
253
      {
 
254
         tabprint( fd, tab_level+1, "type =" ) ;
 
255
         for ( nvp = &service_types[ 0 ] ; nvp->name != NULL ; nvp++ )
 
256
            if ( M_IS_SET( SC_TYPE(scp), nvp->value ) )
 
257
               Sprint( fd, " %s", nvp->name ) ;
 
258
         Sputchar( fd, '\n' ) ;
 
259
      }
 
260
 
 
261
      tabprint( fd, tab_level+1, "socket_type = %s\n",
 
262
         nv_get_name( socket_types, SC_SOCKET_TYPE(scp) ) ) ;
 
263
 
 
264
      tabprint( fd, tab_level+1, "Protocol (name,number) = (%s,%d)\n",
 
265
            SC_PROTONAME(scp), SC_PROTOVAL(scp) ) ;
 
266
      
 
267
      if ( SC_SPECIFIED( scp, A_PORT ) )
 
268
         tabprint( fd, tab_level+1, "port = %d\n", SC_PORT(scp) ) ;
 
269
   }
 
270
 
 
271
   if ( SC_SPECIFIED( scp, A_INSTANCES ) ) {
 
272
      if ( SC_INSTANCES(scp) == UNLIMITED )
 
273
         tabprint( fd, tab_level+1, "Instances = UNLIMITED\n" ) ;
 
274
      else
 
275
         tabprint( fd, tab_level+1, "Instances = %d\n", SC_INSTANCES(scp) ) ;
 
276
   }
 
277
 
 
278
   if ( SC_SPECIFIED( scp, A_WAIT ) ) {
 
279
      if ( SC_WAIT(scp) )
 
280
         tabprint( fd, tab_level+1, "wait = yes\n" ) ;
 
281
      else
 
282
         tabprint( fd, tab_level+1, "wait = no\n" ) ;
 
283
   }
 
284
      
 
285
   if ( SC_SPECIFIED( scp, A_USER ) )
 
286
      tabprint( fd, tab_level+1, "user = %d\n", SC_UID(scp) ) ;
 
287
      
 
288
   if ( SC_SPECIFIED( scp, A_GROUP ) )
 
289
      tabprint( fd, tab_level+1, "group = %d\n", SC_GID(scp) ) ;
 
290
      
 
291
   if ( SC_SPECIFIED( scp, A_GROUPS ) )
 
292
   {
 
293
      if (SC_GROUPS(scp) == 1)
 
294
         tabprint( fd, tab_level+1, "Groups = yes\n" );
 
295
      else
 
296
         tabprint( fd, tab_level+1, "Groups = no\n" );
 
297
   }
 
298
 
 
299
   if ( SC_SPECIFIED( scp, A_UMASK ) )
 
300
      tabprint( fd, tab_level+1, "umask = %o\n", SC_UMASK(scp) ) ;
 
301
      
 
302
   if ( SC_SPECIFIED( scp, A_NICE ) )
 
303
      tabprint( fd, tab_level+1, "Nice = %d\n", SC_NICE(scp) ) ;
 
304
 
 
305
   if ( SC_SPECIFIED( scp, A_CPS ) )
 
306
      tabprint( fd, tab_level+1, "CPS = max conn:%lu wait:%lu\n", 
 
307
         SC_TIME_CONN_MAX(scp), SC_TIME_WAIT(scp) );
 
308
 
 
309
   if ( SC_SPECIFIED( scp, A_PER_SOURCE ) )
 
310
      tabprint( fd, tab_level+1, "PER_SOURCE = %d\n", 
 
311
         SC_PER_SOURCE(scp) );
 
312
 
 
313
   if ( SC_SPECIFIED( scp, A_BIND ) ) {
 
314
           if (  SC_BIND_ADDR(scp) ) {
 
315
                  char bindname[NI_MAXHOST];
 
316
                  unsigned int len = 0;
 
317
                  if( SC_BIND_ADDR(scp)->sa.sa_family == AF_INET ) 
 
318
                         len = sizeof(struct sockaddr_in);
 
319
                  else  
 
320
                         len = sizeof(struct sockaddr_in6);
 
321
                  memset(bindname, 0, sizeof(bindname));
 
322
                  if( getnameinfo(&SC_BIND_ADDR(scp)->sa, len, bindname, 
 
323
                                  NI_MAXHOST, NULL, 0, 0) != 0 ) 
 
324
                         strcpy(bindname, "unknown");
 
325
                  tabprint( fd, tab_level+1, "Bind = %s\n", bindname );
 
326
           }
 
327
           else if ( SC_ORIG_BIND_ADDR(scp) ) {
 
328
                  tabprint( fd, tab_level+1, "Bind = %s\n", 
 
329
                            SC_ORIG_BIND_ADDR(scp) );
 
330
           }
 
331
           else { /* This should NEVER happen */
 
332
                msg(LOG_ERR, "sc_dump", "bad configuration for %s:", 
 
333
                    SC_NAME(scp));
 
334
           }
 
335
   }
 
336
   else
 
337
      tabprint( fd, tab_level+1, "Bind = All addresses.\n" );
 
338
 
 
339
   if ( ! is_defaults )
 
340
   {
 
341
      if ( (! SC_IS_INTERNAL( scp )) && (SC_REDIR_ADDR(scp) == NULL) )
 
342
      {
 
343
         tabprint( fd, tab_level+1, "Server = %s\n", SC_SERVER(scp) ) ;
 
344
         tabprint( fd, tab_level+1, "Server argv =" ) ;
 
345
         if ( SC_SERVER_ARGV(scp) )
 
346
         {
 
347
            for ( pp = SC_SERVER_ARGV(scp) ; *pp ; pp++ )
 
348
               Sprint( fd, " %s", *pp ) ;
 
349
         }
 
350
         else
 
351
            Sprint( fd, " (NULL)");
 
352
         Sputchar( fd, '\n' ) ;
 
353
      } 
 
354
 
 
355
      if ( SC_REDIR_ADDR(scp) != NULL ) 
 
356
      {
 
357
         char redirname[NI_MAXHOST];
 
358
         unsigned int len = 0;
 
359
         if( SC_REDIR_ADDR(scp)->sa.sa_family == AF_INET ) 
 
360
            len = sizeof(struct sockaddr_in);
 
361
         if( SC_REDIR_ADDR(scp)->sa.sa_family == AF_INET6 ) 
 
362
            len = sizeof(struct sockaddr_in6);
 
363
         memset(redirname, 0, sizeof(redirname));
 
364
         if( getnameinfo(&SC_REDIR_ADDR(scp)->sa, len,  redirname, NI_MAXHOST, 
 
365
               NULL, 0, 0) != 0 ) 
 
366
            strcpy(redirname, "unknown");
 
367
         tabprint( fd, tab_level+1, "Redirect = %s:%d\n", redirname, 
 
368
            SC_REDIR_ADDR(scp)->sa_in.sin_port );
 
369
      }
 
370
 
 
371
      if ( SC_IS_RPC( scp ) )
 
372
      {
 
373
         struct rpc_data *rdp = SC_RPCDATA( scp ) ;
 
374
 
 
375
         tabprint( fd, tab_level+1, "RPC data\n" ) ;
 
376
         tabprint( fd, tab_level+2,
 
377
                           "program number = %ld\n", rdp->rd_program_number ) ;
 
378
         tabprint( fd, tab_level+2, "rpc_version = " ) ;
 
379
         if ( rdp->rd_min_version == rdp->rd_max_version )
 
380
            Sprint( fd, "%ld\n", rdp->rd_min_version ) ;
 
381
         else
 
382
            Sprint( fd, "%ld-%ld\n",
 
383
                           rdp->rd_min_version, rdp->rd_max_version ) ;
 
384
      }
 
385
 
 
386
      if ( SC_SPECIFIED( scp, A_ACCESS_TIMES ) )
 
387
      {
 
388
         tabprint( fd, tab_level+1, "Access times =" ) ;
 
389
         ti_dump( SC_ACCESS_TIMES(scp), fd ) ;
 
390
         Sputchar ( fd, '\n' ) ;
 
391
      }
 
392
   }
 
393
 
 
394
   /* This is important enough that each service should list it. */
 
395
   tabprint( fd, tab_level+1, "Only from: " ) ;
 
396
   if ( SC_ONLY_FROM(scp) )
 
397
   {  /* Next check is done since -= doesn't zero out lists. */
 
398
      if ( pset_count(SC_ONLY_FROM(scp)) == 0)
 
399
         Sprint( fd, "All sites" );
 
400
      else
 
401
         addrlist_dump( SC_ONLY_FROM(scp), fd ) ;
 
402
   }
 
403
   else
 
404
      Sprint( fd, "All sites" );
 
405
   Sputchar( fd, '\n' ) ;
 
406
 
 
407
   /* This is important enough that each service should list it. */
 
408
   tabprint( fd, tab_level+1, "No access: " ) ;
 
409
   if ( SC_NO_ACCESS(scp) )
 
410
   {  /* Next check is done since -= doesn't zero out lists. */
 
411
      if ( pset_count(SC_NO_ACCESS(scp)) == 0)
 
412
         Sprint( fd, "No blocked sites" );
 
413
      else
 
414
         addrlist_dump( SC_NO_ACCESS(scp), fd ) ;
 
415
   }
 
416
   else
 
417
      Sprint( fd, "No blocked sites" );
 
418
   Sputchar( fd, '\n' ) ;
 
419
 
 
420
   if ( SC_SENSOR(scp) )
 
421
   {
 
422
      tabprint( fd, tab_level+1, "Deny Time: " ) ;
 
423
      Sprint( fd, "%d\n", SC_DENY_TIME(scp));
 
424
   }
 
425
   
 
426
   dump_log_data( fd, scp, tab_level+1 ) ;
 
427
 
 
428
   if ( SC_IS_PRESENT( scp, A_PASSENV ) )
 
429
   {
 
430
      tabprint( fd, tab_level+1, "Passenv =" ) ;
 
431
      for ( u = 0 ; u < pset_count( SC_PASS_ENV_VARS(scp) ) ; u++ )
 
432
         Sprint( fd, " %s",
 
433
                  (char *) pset_pointer( SC_PASS_ENV_VARS(scp), u ) ) ;
 
434
      Sputchar ( fd, '\n' ) ;
 
435
   }
 
436
 
 
437
   if ( ! is_defaults )
 
438
      if ( SC_SPECIFIED( scp, A_ENV ) )
 
439
      {
 
440
         tabprint( fd, tab_level+1, "Environment additions:\n" ) ;
 
441
         for ( u = 0 ; u < pset_count( SC_ENV_VAR_DEFS(scp) ) ; u++ )
 
442
            tabprint( fd, tab_level+2,
 
443
                  "%s\n", (char *) pset_pointer( SC_ENV_VAR_DEFS(scp), u ) ) ;
 
444
      }
 
445
   
 
446
   if ( SC_ENV( scp )->env_type == CUSTOM_ENV )
 
447
   {
 
448
      tabprint( fd, tab_level+1, "Environment strings:\n" ) ;
 
449
      for ( pp = env_getvars( SC_ENV( scp )->env_handle ) ; *pp ; pp++ )
 
450
         tabprint( fd, tab_level+2, "%s\n", *pp ) ;
 
451
   }
 
452
   Sflush( fd ) ;
 
453
}
 
454
 
 
455
 
 
456
#define SC_RPCPROGNUM( s )    RD_PROGNUM( SC_RPCDATA( s ) )
 
457
#define SAME_RPC( s1, s2 )    ( SC_RPCPROGNUM( s1 ) == SC_RPCPROGNUM( s2 ) )
 
458
#define SAME_NONRPC( s1, s2 ) ( SC_SOCKET_TYPE((s1)) == SC_SOCKET_TYPE((s2)) \
 
459
                                 && SC_PORT((s1)) == SC_PORT((s2)) )
 
460
 
 
461
/*
 
462
 * Two service configurations are considered different if any of the
 
463
 * following is TRUE:
 
464
 *      1) only one is unlisted
 
465
 *      2) only one is internal
 
466
 *      3) only one is RPC
 
467
 *      4) they have different values for the 'wait' attribute
 
468
 *      5) they use different protocols
 
469
 *      6) they are both RPC services but have different program numbers
 
470
 *      7) neither is an RPC service and they have different socket_types or
 
471
 *         use diffent ports
 
472
 *
 
473
 * This function returns TRUE if the specified configurations are different.
 
474
 *
 
475
 * Note that this function is closely related to the 'readjust' function
 
476
 * that is invoked on reconfiguration; that function will not change 
 
477
 * attributes that this function checks to determine if two configurations
 
478
 * are different.
 
479
 */
 
480
bool_int sc_different_confs( struct service_config *scp1, 
 
481
                             struct service_config *scp2 )
 
482
{
 
483
   if ( SC_IS_UNLISTED( scp1 ) != SC_IS_UNLISTED( scp2 ) ||
 
484
            SC_IS_INTERNAL( scp1 ) != SC_IS_INTERNAL( scp2 ) ||
 
485
               SC_IS_RPC( scp1 ) != SC_IS_RPC( scp2 ) )
 
486
      return( TRUE ) ;
 
487
 
 
488
   if ( SC_WAIT(scp1) != SC_WAIT(scp2) )
 
489
      return( TRUE ) ;
 
490
  
 
491
   if ( SC_PROTOVAL(scp1) != SC_PROTOVAL(scp2) )
 
492
      return( TRUE ) ;
 
493
 
 
494
   if ( SC_IS_RPC( scp1 ) )
 
495
   {
 
496
      if ( ! SAME_RPC( scp1, scp2 ) )
 
497
         return( TRUE ) ;
 
498
   }
 
499
   else
 
500
   {
 
501
      if ( ! SAME_NONRPC( scp1, scp2 ) )
 
502
         return( TRUE ) ;
 
503
   }
 
504
   return( FALSE ) ;
 
505
}
 
506