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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE book PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
<chapter id="CodingSuggestions">
<chapterinfo>
<author>
<firstname>Steve</firstname><surname>French</surname>
</author>
<author>
<firstname>Simo</firstname><surname>Sorce</surname>
</author>
<author>
<firstname>Andrew</firstname><surname>Bartlett</surname>
</author>
<author>
<firstname>Tim</firstname><surname>Potter</surname>
</author>
<author>
<firstname>Martin</firstname><surname>Pool</surname>
</author>
</chapterinfo>
<title>Coding Suggestions</title>
<para>
So you want to add code to Samba ...
</para>
<para>
One of the daunting tasks facing a programmer attempting to write code for
Samba is understanding the various coding conventions used by those most
active in the project. These conventions were mostly unwritten and helped
improve either the portability, stability or consistency of the code. This
document will attempt to document a few of the more important coding
practices used at this time on the Samba project. The coding practices are
expected to change slightly over time, and even to grow as more is learned
about obscure portability considerations. Two existing documents
<filename>samba/source/internals.doc</filename> and
<filename>samba/source/architecture.doc</filename> provide
additional information.
</para>
<para>
The loosely related question of coding style is very personal and this
document does not attempt to address that subject, except to say that I
have observed that eight character tabs seem to be preferred in Samba
source. If you are interested in the topic of coding style, two oft-quoted
documents are:
</para>
<para>
<ulink url="http://lxr.linux.no/source/Documentation/CodingStyle">http://lxr.linux.no/source/Documentation/CodingStyle</ulink>
</para>
<para>
<ulink url="http://www.fsf.org/prep/standards_toc.html">http://www.fsf.org/prep/standards_toc.html</ulink>
</para>
<para>
But note that coding style in Samba varies due to the many different
programmers who have contributed.
</para>
<para>
Following are some considerations you should use when adding new code to
Samba. First and foremost remember that:
</para>
<para>
Portability is a primary consideration in adding function, as is network
compatability with de facto, existing, real world CIFS/SMB implementations.
There are lots of platforms that Samba builds on so use caution when adding
a call to a library function that is not invoked in existing Samba code.
Also note that there are many quite different SMB/CIFS clients that Samba
tries to support, not all of which follow the SNIA CIFS Technical Reference
(or the earlier Microsoft reference documents or the X/Open book on the SMB
Standard) perfectly.
</para>
<para>
Here are some other suggestions:
</para>
<orderedlist>
<listitem><para>
use d_printf instead of printf for display text
reason: enable auto-substitution of translated language text
</para></listitem>
<listitem><para>
use SAFE_FREE instead of free
reason: reduce traps due to null pointers
</para></listitem>
<listitem><para>
don't use bzero use memset, or ZERO_STRUCT and ZERO_STRUCTP macros
reason: not POSIX
</para></listitem>
<listitem><para>
don't use strcpy and strlen (use safe_* equivalents)
reason: to avoid traps due to buffer overruns
</para></listitem>
<listitem><para>
don't use getopt_long, use popt functions instead
reason: portability
</para></listitem>
<listitem><para>
explicitly add const qualifiers on parm passing in functions where parm
is input only (somewhat controversial but const can be #defined away)
</para></listitem>
<listitem><para>
when passing a va_list as an arg, or assigning one to another
please use the VA_COPY() macro
reason: on some platforms, va_list is a struct that must be
initialized in each function...can SEGV if you don't.
</para></listitem>
<listitem><para>
discourage use of threads
reason: portability (also see architecture.doc)
</para></listitem>
<listitem><para>
don't explicitly include new header files in C files - new h files
should be included by adding them once to includes.h
reason: consistency
</para></listitem>
<listitem><para>
don't explicitly extern functions (they are autogenerated by
"make proto" into proto.h)
reason: consistency
</para></listitem>
<listitem><para>
use endian safe macros when unpacking SMBs (see byteorder.h and
internals.doc)
reason: not everyone uses Intel
</para></listitem>
<listitem><para>
Note Unicode implications of charset handling (see internals.doc). See
pull_* and push_* and convert_string functions.
reason: Internationalization
</para></listitem>
<listitem><para>
Don't assume English only
reason: See above
</para></listitem>
<listitem><para>
Try to avoid using in/out parameters (functions that return data which
overwrites input parameters)
reason: Can cause stability problems
</para></listitem>
<listitem><para>
Ensure copyright notices are correct, don't append Tridge's name to code
that he didn't write. If you did not write the code, make sure that it
can coexist with the rest of the Samba GPLed code.
</para></listitem>
<listitem><para>
Consider usage of DATA_BLOBs for length specified byte-data.
reason: stability
</para></listitem>
<listitem><para>
Take advantage of tdbs for database like function
reason: consistency
</para></listitem>
<listitem><para>
Don't access the SAM_ACCOUNT structure directly, they should be accessed
via pdb_get...() and pdb_set...() functions.
reason: stability, consistency
</para></listitem>
<listitem><para>
Don't check a password directly against the passdb, always use the
check_password() interface.
reason: long term pluggability
</para></listitem>
<listitem><para>
Try to use asprintf rather than pstrings and fstrings where possible
</para></listitem>
<listitem><para>
Use normal C comments / * instead of C++ comments // like
this. Although the C++ comment format is part of the C99
standard, some older vendor C compilers do not accept it.
</para></listitem>
<listitem><para>
Try to write documentation for API functions and structures
explaining the point of the code, the way it should be used, and
any special conditions or results. Mark these with a double-star
comment start / ** so that they can be picked up by Doxygen, as in
this file.
</para></listitem>
<listitem><para>
Keep the scope narrow. This means making functions/variables
static whenever possible. We don't want our namespace
polluted. Each module should have a minimal number of externally
visible functions or variables.
</para></listitem>
<listitem><para>
Use function pointers to keep knowledge about particular pieces of
code isolated in one place. We don't want a particular piece of
functionality to be spread out across lots of places - that makes
for fragile, hand to maintain code. Instead, design an interface
and use tables containing function pointers to implement specific
functionality. This is particularly important for command
interpreters.
</para></listitem>
<listitem><para>
Think carefully about what it will be like for someone else to add
to and maintain your code. If it would be hard for someone else to
maintain then do it another way.
</para></listitem>
</orderedlist>
<para>
The suggestions above are simply that, suggestions, but the information may
help in reducing the routine rework done on new code. The preceeding list
is expected to change routinely as new support routines and macros are
added.
</para>
</chapter>
|