| 1 | <?xml version="1.0" encoding="iso-8859-1"?> | 
|---|
| 2 | <!DOCTYPE chapter PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> | 
|---|
| 3 | <chapter id="CodingSuggestions"> | 
|---|
| 4 | <chapterinfo> | 
|---|
| 5 | <author> | 
|---|
| 6 | <firstname>Steve</firstname><surname>French</surname> | 
|---|
| 7 | </author> | 
|---|
| 8 | <author> | 
|---|
| 9 | <firstname>Simo</firstname><surname>Sorce</surname> | 
|---|
| 10 | </author> | 
|---|
| 11 | <author> | 
|---|
| 12 | <firstname>Andrew</firstname><surname>Bartlett</surname> | 
|---|
| 13 | </author> | 
|---|
| 14 | <author> | 
|---|
| 15 | <firstname>Tim</firstname><surname>Potter</surname> | 
|---|
| 16 | </author> | 
|---|
| 17 | <author> | 
|---|
| 18 | <firstname>Martin</firstname><surname>Pool</surname> | 
|---|
| 19 | </author> | 
|---|
| 20 | </chapterinfo> | 
|---|
| 21 |  | 
|---|
| 22 | <title>Coding Suggestions</title> | 
|---|
| 23 |  | 
|---|
| 24 | <para> | 
|---|
| 25 | So you want to add code to Samba ... | 
|---|
| 26 | </para> | 
|---|
| 27 |  | 
|---|
| 28 | <para> | 
|---|
| 29 | One of the daunting tasks facing a programmer attempting to write code for | 
|---|
| 30 | Samba is understanding the various coding conventions used by those most | 
|---|
| 31 | active in the project.  These conventions were mostly unwritten and helped | 
|---|
| 32 | improve either the portability, stability or consistency of the code. This | 
|---|
| 33 | document will attempt to document a few of the more important coding | 
|---|
| 34 | practices used at this time on the Samba project.  The coding practices are | 
|---|
| 35 | expected to change slightly over time, and even to grow as more is learned | 
|---|
| 36 | about obscure portability considerations.  Two existing documents | 
|---|
| 37 | <filename>samba/source/internals.doc</filename> and | 
|---|
| 38 | <filename>samba/source/architecture.doc</filename> provide | 
|---|
| 39 | additional information. | 
|---|
| 40 | </para> | 
|---|
| 41 |  | 
|---|
| 42 | <para> | 
|---|
| 43 | The loosely related question of coding style is very personal and this | 
|---|
| 44 | document does not attempt to address that subject, except to say that I | 
|---|
| 45 | have observed that eight character tabs seem to be preferred in Samba | 
|---|
| 46 | source.  If you are interested in the topic of coding style, two oft-quoted | 
|---|
| 47 | documents are: | 
|---|
| 48 | </para> | 
|---|
| 49 |  | 
|---|
| 50 | <para> | 
|---|
| 51 | <ulink url="http://lxr.linux.no/source/Documentation/CodingStyle">http://lxr.linux.no/source/Documentation/CodingStyle</ulink> | 
|---|
| 52 | </para> | 
|---|
| 53 |  | 
|---|
| 54 | <para> | 
|---|
| 55 | <ulink url="http://www.fsf.org/prep/standards_toc.html">http://www.fsf.org/prep/standards_toc.html</ulink> | 
|---|
| 56 | </para> | 
|---|
| 57 |  | 
|---|
| 58 | <para> | 
|---|
| 59 | But note that coding style in Samba varies due to the many different | 
|---|
| 60 | programmers who have contributed. | 
|---|
| 61 | </para> | 
|---|
| 62 |  | 
|---|
| 63 | <para> | 
|---|
| 64 | Following are some considerations you should use when adding new code to | 
|---|
| 65 | Samba.  First and foremost remember that: | 
|---|
| 66 | </para> | 
|---|
| 67 |  | 
|---|
| 68 | <para> | 
|---|
| 69 | Portability is a primary consideration in adding function, as is network | 
|---|
| 70 | compatability with de facto, existing, real world CIFS/SMB implementations. | 
|---|
| 71 | There are lots of platforms that Samba builds on so use caution when adding | 
|---|
| 72 | a call to a library function that is not invoked in existing Samba code. | 
|---|
| 73 | Also note that there are many quite different SMB/CIFS clients that Samba | 
|---|
| 74 | tries to support, not all of which follow the SNIA CIFS Technical Reference | 
|---|
| 75 | (or the earlier Microsoft reference documents or the X/Open book on the SMB | 
|---|
| 76 | Standard) perfectly. | 
|---|
| 77 | </para> | 
|---|
| 78 |  | 
|---|
| 79 | <para> | 
|---|
| 80 | Here are some other suggestions: | 
|---|
| 81 | </para> | 
|---|
| 82 |  | 
|---|
| 83 | <orderedlist> | 
|---|
| 84 |  | 
|---|
| 85 | <listitem><para> | 
|---|
| 86 | use d_printf instead of printf for display text | 
|---|
| 87 | reason: enable auto-substitution of translated language text | 
|---|
| 88 | </para></listitem> | 
|---|
| 89 |  | 
|---|
| 90 | <listitem><para> | 
|---|
| 91 | use SAFE_FREE instead of free | 
|---|
| 92 | reason: reduce traps due to null pointers | 
|---|
| 93 | </para></listitem> | 
|---|
| 94 |  | 
|---|
| 95 | <listitem><para> | 
|---|
| 96 | don't use bzero use memset, or ZERO_STRUCT and ZERO_STRUCTP macros | 
|---|
| 97 | reason: not POSIX | 
|---|
| 98 | </para></listitem> | 
|---|
| 99 |  | 
|---|
| 100 | <listitem><para> | 
|---|
| 101 | don't use strcpy and strlen (use safe_* equivalents) | 
|---|
| 102 | reason: to avoid traps due to buffer overruns | 
|---|
| 103 | </para></listitem> | 
|---|
| 104 |  | 
|---|
| 105 | <listitem><para> | 
|---|
| 106 | don't use getopt_long, use popt functions instead | 
|---|
| 107 | reason: portability | 
|---|
| 108 | </para></listitem> | 
|---|
| 109 |  | 
|---|
| 110 | <listitem><para> | 
|---|
| 111 | explicitly add const qualifiers on parm passing in functions where parm | 
|---|
| 112 | is input only (somewhat controversial but const can be #defined away) | 
|---|
| 113 | </para></listitem> | 
|---|
| 114 |  | 
|---|
| 115 | <listitem><para> | 
|---|
| 116 | when passing a va_list as an arg, or assigning one to another | 
|---|
| 117 | please use the VA_COPY() macro | 
|---|
| 118 | reason: on some platforms, va_list is a struct that must be | 
|---|
| 119 | initialized in each function...can SEGV if you don't. | 
|---|
| 120 | </para></listitem> | 
|---|
| 121 |  | 
|---|
| 122 | <listitem><para> | 
|---|
| 123 | discourage use of threads | 
|---|
| 124 | reason: portability (also see architecture.doc) | 
|---|
| 125 | </para></listitem> | 
|---|
| 126 |  | 
|---|
| 127 | <listitem><para> | 
|---|
| 128 | don't explicitly include new header files in C files - new h files | 
|---|
| 129 | should be included by adding them once to includes.h | 
|---|
| 130 | reason: consistency | 
|---|
| 131 | </para></listitem> | 
|---|
| 132 |  | 
|---|
| 133 | <listitem><para> | 
|---|
| 134 | don't explicitly extern functions (they are autogenerated by | 
|---|
| 135 | "make proto" into proto.h) | 
|---|
| 136 | reason: consistency | 
|---|
| 137 | </para></listitem> | 
|---|
| 138 |  | 
|---|
| 139 | <listitem><para> | 
|---|
| 140 | use endian safe macros when unpacking SMBs (see byteorder.h and | 
|---|
| 141 | internals.doc) | 
|---|
| 142 | reason: not everyone uses Intel | 
|---|
| 143 | </para></listitem> | 
|---|
| 144 |  | 
|---|
| 145 | <listitem><para> | 
|---|
| 146 | Note Unicode implications of charset handling (see internals.doc).  See | 
|---|
| 147 | pull_*  and push_* and convert_string functions. | 
|---|
| 148 | reason: Internationalization | 
|---|
| 149 | </para></listitem> | 
|---|
| 150 |  | 
|---|
| 151 | <listitem><para> | 
|---|
| 152 | Don't assume English only | 
|---|
| 153 | reason: See above | 
|---|
| 154 | </para></listitem> | 
|---|
| 155 |  | 
|---|
| 156 | <listitem><para> | 
|---|
| 157 | Try to avoid using in/out parameters (functions that return data which | 
|---|
| 158 | overwrites input parameters) | 
|---|
| 159 | reason: Can cause stability problems | 
|---|
| 160 | </para></listitem> | 
|---|
| 161 |  | 
|---|
| 162 | <listitem><para> | 
|---|
| 163 | Ensure copyright notices are correct, don't append Tridge's name to code | 
|---|
| 164 | that he didn't write.  If you did not write the code, make sure that it | 
|---|
| 165 | can coexist with the rest of the Samba GPLed code. | 
|---|
| 166 | </para></listitem> | 
|---|
| 167 |  | 
|---|
| 168 | <listitem><para> | 
|---|
| 169 | Consider usage of DATA_BLOBs for length specified byte-data. | 
|---|
| 170 | reason: stability | 
|---|
| 171 | </para></listitem> | 
|---|
| 172 |  | 
|---|
| 173 | <listitem><para> | 
|---|
| 174 | Take advantage of tdbs for database like function | 
|---|
| 175 | reason: consistency | 
|---|
| 176 | </para></listitem> | 
|---|
| 177 |  | 
|---|
| 178 | <listitem><para> | 
|---|
| 179 | Don't access the SAM_ACCOUNT structure directly, they should be accessed | 
|---|
| 180 | via pdb_get...() and pdb_set...() functions. | 
|---|
| 181 | reason: stability, consistency | 
|---|
| 182 | </para></listitem> | 
|---|
| 183 |  | 
|---|
| 184 | <listitem><para> | 
|---|
| 185 | Don't check a password directly against the passdb, always use the | 
|---|
| 186 | check_password() interface. | 
|---|
| 187 | reason: long term pluggability | 
|---|
| 188 | </para></listitem> | 
|---|
| 189 |  | 
|---|
| 190 | <listitem><para> | 
|---|
| 191 | Try to use asprintf rather than pstrings and fstrings where possible | 
|---|
| 192 | </para></listitem> | 
|---|
| 193 |  | 
|---|
| 194 | <listitem><para> | 
|---|
| 195 | Use normal C comments / * instead of C++ comments // like | 
|---|
| 196 | this.  Although the C++ comment format is part of the C99 | 
|---|
| 197 | standard, some older vendor C compilers do not accept it. | 
|---|
| 198 | </para></listitem> | 
|---|
| 199 |  | 
|---|
| 200 | <listitem><para> | 
|---|
| 201 | Try to write documentation for API functions and structures | 
|---|
| 202 | explaining the point of the code, the way it should be used, and | 
|---|
| 203 | any special conditions or results.  Mark these with a double-star | 
|---|
| 204 | comment start / ** so that they can be picked up by Doxygen, as in | 
|---|
| 205 | this file. | 
|---|
| 206 | </para></listitem> | 
|---|
| 207 |  | 
|---|
| 208 | <listitem><para> | 
|---|
| 209 | Keep the scope narrow. This means making functions/variables | 
|---|
| 210 | static whenever possible. We don't want our namespace | 
|---|
| 211 | polluted. Each module should have a minimal number of externally | 
|---|
| 212 | visible functions or variables. | 
|---|
| 213 | </para></listitem> | 
|---|
| 214 |  | 
|---|
| 215 | <listitem><para> | 
|---|
| 216 | Use function pointers to keep knowledge about particular pieces of | 
|---|
| 217 | code isolated in one place. We don't want a particular piece of | 
|---|
| 218 | functionality to be spread out across lots of places - that makes | 
|---|
| 219 | for fragile, hand to maintain code. Instead, design an interface | 
|---|
| 220 | and use tables containing function pointers to implement specific | 
|---|
| 221 | functionality. This is particularly important for command | 
|---|
| 222 | interpreters. | 
|---|
| 223 | </para></listitem> | 
|---|
| 224 |  | 
|---|
| 225 | <listitem><para> | 
|---|
| 226 | Think carefully about what it will be like for someone else to add | 
|---|
| 227 | to and maintain your code. If it would be hard for someone else to | 
|---|
| 228 | maintain then do it another way. | 
|---|
| 229 | </para></listitem> | 
|---|
| 230 |  | 
|---|
| 231 | </orderedlist> | 
|---|
| 232 |  | 
|---|
| 233 | <para> | 
|---|
| 234 | The suggestions above are simply that, suggestions, but the information may | 
|---|
| 235 | help in reducing the routine rework done on new code.  The preceeding list | 
|---|
| 236 | is expected to change routinely as new support routines and macros are | 
|---|
| 237 | added. | 
|---|
| 238 | </para> | 
|---|
| 239 | </chapter> | 
|---|