Bonjour,

J'ai réccupéré sur le net un projet en C écrit il y'a 20 ans et non mis à jour depuis 10 ans. C'est une implémentation des ONC RPC pour windows.

Il est indiqué que le code compilait avec VC++ et Borland, mais je n'ai pas ces compilateurs sous la main, et encore moins dans leur version d'il y'a 10 ans. Je voudrais le compiler avec les outils GNU de MinGW.

Je suis tombé sur une syntaxe que je ne comprends pas (et qui ne compile pas d'ailleurs). Voici le fichier concerné (auth.h) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#ifndef __AUTH_HEADER__
#define __AUTH_HEADER__
 
#ifdef __cplusplus
extern "C" {
#define DOTS ...
#else
#define DOTS
#endif
 
#define MAX_AUTH_BYTES    400
#define MAXNETNAMELEN    255    /* maximum length of network user's name */
 
/*
 * Status returned from authentication check
 */
enum auth_stat {
    AUTH_OK=0,
    /*
     * failed at remote end
     */
    AUTH_BADCRED=1,            /* bogus credentials (seal broken) */
    AUTH_REJECTEDCRED=2,        /* client should begin new session */
    AUTH_BADVERF=3,            /* bogus verifier (seal broken) */
    AUTH_REJECTEDVERF=4,        /* verifier expired or was replayed */
    AUTH_TOOWEAK=5,            /* rejected due to security reasons */
    /*
     * failed locally
    */
    AUTH_INVALIDRESP=6,        /* bogus response verifier */
    AUTH_FAILED=7            /* some unknown reason */
};
 
#if (mc68000 || sparc || vax || i386)
typedef u_long u_int32;    /* 32-bit unsigned integers */
 
union des_block {
    struct {
        u_int32 high;
        u_int32 low;
    } key;
    char c[8];
};
#else
union des_block {
        struct {
                u_long high;
                u_long low;
        } key;
        char c[8];
};
#endif
typedef union des_block des_block;
extern bool_t xdr_des_block(DOTS);
 
/*
 * Authentication info.  Opaque to client.
 */
struct opaque_auth {
    enum_t    oa_flavor;        /* flavor of auth */
    caddr_t    oa_base;        /* address of more auth stuff */
    u_int    oa_length;        /* not to exceed MAX_AUTH_BYTES */
};
 
 
/*
 * Auth handle, interface to client side authenticators.
 */
typedef struct {
    struct    opaque_auth    ah_cred;
    struct    opaque_auth    ah_verf;
    union    des_block    ah_key;
    struct auth_ops {
        void    (*ah_nextverf)(DOTS);
        int    (*ah_marshal)(DOTS);    /* nextverf & serialize */
        int    (*ah_validate)(DOTS);    /* validate varifier */
        int    (*ah_refresh)(DOTS);    /* refresh credentials */
        void    (*ah_destroy)(DOTS);    /* destroy this structure */
    } *ah_ops;
    caddr_t ah_private;
} AUTH;
 
 
/*
 * Authentication ops.
 * The ops and the auth handle provide the interface to the authenticators.
 *
 * AUTH    *auth;
 * XDR    *xdrs;
 * struct opaque_auth verf;
 */
#define AUTH_NEXTVERF(auth)        \
        ((*((auth)->ah_ops->ah_nextverf))(auth))
#define auth_nextverf(auth)        \
        ((*((auth)->ah_ops->ah_nextverf))(auth))
 
#define AUTH_MARSHALL(auth, xdrs)    \
        ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
#define auth_marshall(auth, xdrs)    \
        ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
 
#define AUTH_VALIDATE(auth, verfp)    \
        ((*((auth)->ah_ops->ah_validate))((auth), verfp))
#define auth_validate(auth, verfp)    \
        ((*((auth)->ah_ops->ah_validate))((auth), verfp))
 
#define AUTH_REFRESH(auth)        \
        ((*((auth)->ah_ops->ah_refresh))(auth))
#define auth_refresh(auth)        \
        ((*((auth)->ah_ops->ah_refresh))(auth))
 
#define AUTH_DESTROY(auth)        \
        ((*((auth)->ah_ops->ah_destroy))(auth))
#define auth_destroy(auth)        \
        ((*((auth)->ah_ops->ah_destroy))(auth))
 
#ifdef WIN32
#ifdef ONCRPCDLL
extern struct opaque_auth _null_auth;
#else
#ifdef __BORLANDC__
extern __declspec(dllimport) struct opaque_auth _null_auth;
#else
_declspec(dllimport) struct opaque_auth _null_auth;
#endif
#endif
#else
extern struct opaque_auth _null_auth;
#endif
 
 
/*
 * These are the various implementations of client side authenticators.
 */
 
/*
 * Unix style authentication
 * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
 *    char *machname;
 *    int uid;
 *    int gid;
 *    int len;
 *    int *aup_gids;
 */
extern AUTH *authunix_create(DOTS);
extern AUTH *authunix_create_default(DOTS);    /* takes no parameters */
extern AUTH *authnone_create(DOTS);        /* takes no parameters */
extern AUTH *authdes_create(DOTS);
 
#define AUTH_NONE    0        /* no authentication */
#define    AUTH_NULL    0        /* backward compatibility */
#define    AUTH_UNIX    1        /* unix style (uid, gids) */
#define    AUTH_SHORT    2        /* short hand unix style */
#define AUTH_DES    3        /* des style (encrypted timestamps) */
 
#ifdef __cplusplus
};
#endif
 
#endif    /* __AUTH_HEADER__ */
et le problème : à quoi sert le #define DOTS en haut, et comment celà est-il sensé fonctionner ? Sachant que ça ne fonctionne pas puisque j'ai une erreur "passing too many parameters" à l'appel de la fonction "auth_marshall" plus loin dans le code.

Je précise que l'auteur a spécifié qu'il n'avait pas porté l'authentification, donc je suppose qu'il a utilisé les DOTS pour faire croire au compilateur que tout va bien, ou quelque chose du genre.

Merci de m'éclairer la dessus, ça m'intéresse vraiment de comprendre le fonctionnement de cette astuce, et surtout de pouvoir réutiliser ce code.