a pastebin project

adml 1.1.0

  1. /*                    GNU GENERAL PUBLIC LICENSE
  2.                        Version 2, June 1991
  3.  
  4. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
  5.                        59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  6. Everyone is permitted to copy and distribute verbatim copies
  7. of this license document, but changing it is not allowed.
  8.  
  9.                             Preamble
  10.  
  11.   The licenses for most software are designed to take away your
  12. freedom to share and change it.  By contrast, the GNU General Public
  13. License is intended to guarantee your freedom to share and change free
  14. software--to make sure the software is free for all its users.  This
  15. General Public License applies to most of the Free Software
  16. Foundation's software and to any other program whose authors commit to
  17. using it.  (Some other Free Software Foundation software is covered by
  18. the GNU Library General Public License instead.)  You can apply it to
  19. your programs, too.
  20.  
  21.   When we speak of free software, we are referring to freedom, not
  22. price.  Our General Public Licenses are designed to make sure that you
  23. have the freedom to distribute copies of free software (and charge for
  24. this service if you wish), that you receive source code or can get it
  25. if you want it, that you can change the software or use pieces of it
  26. in new free programs; and that you know you can do these things.
  27.  
  28.   To protect your rights, we need to make restrictions that forbid
  29. anyone to deny you these rights or to ask you to surrender the rights.
  30. These restrictions translate to certain responsibilities for you if you
  31. distribute copies of the software, or if you modify it.
  32.  
  33.   For example, if you distribute copies of such a program, whether
  34. gratis or for a fee, you must give the recipients all the rights that
  35. you have.  You must make sure that they, too, receive or can get the
  36. source code.  And you must show them these terms so they know their
  37. rights.
  38.  
  39.   We protect your rights with two steps: (1) copyright the software, and
  40. (2) offer you this license which gives you legal permission to copy,
  41. distribute and/or modify the software.
  42.  
  43.   Also, for each author's protection and ours, we want to make certain
  44. that everyone understands that there is no warranty for this free
  45. software.  If the software is modified by someone else and passed on, we
  46. want its recipients to know that what they have is not the original, so
  47. that any problems introduced by others will not reflect on the original
  48. authors' reputations.
  49.  
  50.   Finally, any free program is threatened constantly by software
  51. patents.  We wish to avoid the danger that redistributors of a free
  52. program will individually obtain patent licenses, in effect making the
  53. program proprietary.  To prevent this, we have made it clear that any
  54. patent must be licensed for everyone's free use or not licensed at all.
  55.  
  56.   The precise terms and conditions for copying, distribution and
  57. modification follow.
  58.  
  59.                     GNU GENERAL PUBLIC LICENSE
  60.    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  61.  
  62.   0. This License applies to any program or other work which contains
  63. a notice placed by the copyright holder saying it may be distributed
  64. under the terms of this General Public License.  The "Program", below,
  65. refers to any such program or work, and a "work based on the Program"
  66. means either the Program or any derivative work under copyright law:
  67. that is to say, a work containing the Program or a portion of it,
  68. either verbatim or with modifications and/or translated into another
  69. language.  (Hereinafter, translation is included without limitation in
  70. the term "modification".)  Each licensee is addressed as "you".
  71.  
  72. Activities other than copying, distribution and modification are not
  73. covered by this License; they are outside its scope.  The act of
  74. running the Program is not restricted, and the output from the Program
  75. is covered only if its contents constitute a work based on the
  76. Program (independent of having been made by running the Program).
  77. Whether that is true depends on what the Program does.
  78.  
  79.   1. You may copy and distribute verbatim copies of the Program's
  80. source code as you receive it, in any medium, provided that you
  81. conspicuously and appropriately publish on each copy an appropriate
  82. copyright notice and disclaimer of warranty; keep intact all the
  83. notices that refer to this License and to the absence of any warranty;
  84. and give any other recipients of the Program a copy of this License
  85. along with the Program.
  86.  
  87. You may charge a fee for the physical act of transferring a copy, and
  88. you may at your option offer warranty protection in exchange for a fee.
  89.  
  90.   2. You may modify your copy or copies of the Program or any portion
  91. of it, thus forming a work based on the Program, and copy and
  92. distribute such modifications or work under the terms of Section 1
  93. above, provided that you also meet all of these conditions:
  94.  
  95.     a) You must cause the modified files to carry prominent notices
  96.     stating that you changed the files and the date of any change.
  97.  
  98.     b) You must cause any work that you distribute or publish, that in
  99.     whole or in part contains or is derived from the Program or any
  100.     part thereof, to be licensed as a whole at no charge to all third
  101.     parties under the terms of this License.
  102.  
  103.     c) If the modified program normally reads commands interactively
  104.     when run, you must cause it, when started running for such
  105.     interactive use in the most ordinary way, to print or display an
  106.     announcement including an appropriate copyright notice and a
  107.     notice that there is no warranty (or else, saying that you provide
  108.     a warranty) and that users may redistribute the program under
  109.     these conditions, and telling the user how to view a copy of this
  110.     License.  (Exception: if the Program itself is interactive but
  111.     does not normally print such an announcement, your work based on
  112.     the Program is not required to print an announcement.)
  113.  
  114. These requirements apply to the modified work as a whole.  If
  115. identifiable sections of that work are not derived from the Program,
  116. and can be reasonably considered independent and separate works in
  117. themselves, then this License, and its terms, do not apply to those
  118. sections when you distribute them as separate works.  But when you
  119. distribute the same sections as part of a whole which is a work based
  120. on the Program, the distribution of the whole must be on the terms of
  121. this License, whose permissions for other licensees extend to the
  122. entire whole, and thus to each and every part regardless of who wrote it.
  123.  
  124. Thus, it is not the intent of this section to claim rights or contest
  125. your rights to work written entirely by you; rather, the intent is to
  126. exercise the right to control the distribution of derivative or
  127. collective works based on the Program.
  128.  
  129. In addition, mere aggregation of another work not based on the Program
  130. with the Program (or with a work based on the Program) on a volume of
  131. a storage or distribution medium does not bring the other work under
  132. the scope of this License.
  133.  
  134.   3. You may copy and distribute the Program (or a work based on it,
  135. under Section 2) in object code or executable form under the terms of
  136. Sections 1 and 2 above provided that you also do one of the following:
  137.  
  138.     a) Accompany it with the complete corresponding machine-readable
  139.     source code, which must be distributed under the terms of Sections
  140.     1 and 2 above on a medium customarily used for software interchange; or,
  141.  
  142.     b) Accompany it with a written offer, valid for at least three
  143.     years, to give any third party, for a charge no more than your
  144.     cost of physically performing source distribution, a complete
  145.     machine-readable copy of the corresponding source code, to be
  146.     distributed under the terms of Sections 1 and 2 above on a medium
  147.     customarily used for software interchange; or,
  148.  
  149.     c) Accompany it with the information you received as to the offer
  150.     to distribute corresponding source code.  (This alternative is
  151.     allowed only for noncommercial distribution and only if you
  152.     received the program in object code or executable form with such
  153.     an offer, in accord with Subsection b above.)
  154.  
  155. The source code for a work means the preferred form of the work for
  156. making modifications to it.  For an executable work, complete source
  157. code means all the source code for all modules it contains, plus any
  158. associated interface definition files, plus the scripts used to
  159. control compilation and installation of the executable.  However, as a
  160. special exception, the source code distributed need not include
  161. anything that is normally distributed (in either source or binary
  162. form) with the major components (compiler, kernel, and so on) of the
  163. operating system on which the executable runs, unless that component
  164. itself accompanies the executable.
  165.  
  166. If distribution of executable or object code is made by offering
  167. access to copy from a designated place, then offering equivalent
  168. access to copy the source code from the same place counts as
  169. distribution of the source code, even though third parties are not
  170. compelled to copy the source along with the object code.
  171.  
  172.   4. You may not copy, modify, sublicense, or distribute the Program
  173. except as expressly provided under this License.  Any attempt
  174. otherwise to copy, modify, sublicense or distribute the Program is
  175. void, and will automatically terminate your rights under this License.
  176. However, parties who have received copies, or rights, from you under
  177. this License will not have their licenses terminated so long as such
  178. parties remain in full compliance.
  179.  
  180.   5. You are not required to accept this License, since you have not
  181. signed it.  However, nothing else grants you permission to modify or
  182. distribute the Program or its derivative works.  These actions are
  183. prohibited by law if you do not accept this License.  Therefore, by
  184. modifying or distributing the Program (or any work based on the
  185. Program), you indicate your acceptance of this License to do so, and
  186. all its terms and conditions for copying, distributing or modifying
  187. the Program or works based on it.
  188.  
  189.   6. Each time you redistribute the Program (or any work based on the
  190. Program), the recipient automatically receives a license from the
  191. original licensor to copy, distribute or modify the Program subject to
  192. these terms and conditions.  You may not impose any further
  193. restrictions on the recipients' exercise of the rights granted herein.
  194. You are not responsible for enforcing compliance by third parties to
  195. this License.
  196.  
  197.   7. If, as a consequence of a court judgment or allegation of patent
  198. infringement or for any other reason (not limited to patent issues),
  199. conditions are imposed on you (whether by court order, agreement or
  200. otherwise) that contradict the conditions of this License, they do not
  201. excuse you from the conditions of this License.  If you cannot
  202. distribute so as to satisfy simultaneously your obligations under this
  203. License and any other pertinent obligations, then as a consequence you
  204. may not distribute the Program at all.  For example, if a patent
  205. license would not permit royalty-free redistribution of the Program by
  206. all those who receive copies directly or indirectly through you, then
  207. the only way you could satisfy both it and this License would be to
  208. refrain entirely from distribution of the Program.
  209.  
  210. If any portion of this section is held invalid or unenforceable under
  211. any particular circumstance, the balance of the section is intended to
  212. apply and the section as a whole is intended to apply in other
  213. circumstances.
  214.  
  215. It is not the purpose of this section to induce you to infringe any
  216. patents or other property right claims or to contest validity of any
  217. such claims; this section has the sole purpose of protecting the
  218. integrity of the free software distribution system, which is
  219. implemented by public license practices.  Many people have made
  220. generous contributions to the wide range of software distributed
  221. through that system in reliance on consistent application of that
  222. system; it is up to the author/donor to decide if he or she is willing
  223. to distribute software through any other system and a licensee cannot
  224. impose that choice.
  225.  
  226. This section is intended to make thoroughly clear what is believed to
  227. be a consequence of the rest of this License.
  228.  
  229.   8. If the distribution and/or use of the Program is restricted in
  230. certain countries either by patents or by copyrighted interfaces, the
  231. original copyright holder who places the Program under this License
  232. may add an explicit geographical distribution limitation excluding
  233. those countries, so that distribution is permitted only in or among
  234. countries not thus excluded.  In such case, this License incorporates
  235. the limitation as if written in the body of this License.
  236.  
  237.   9. The Free Software Foundation may publish revised and/or new versions
  238. of the General Public License from time to time.  Such new versions will
  239. be similar in spirit to the present version, but may differ in detail to
  240. address new problems or concerns.
  241.  
  242. Each version is given a distinguishing version number.  If the Program
  243. specifies a version number of this License which applies to it and "any
  244. later version", you have the option of following the terms and conditions
  245. either of that version or of any later version published by the Free
  246. Software Foundation.  If the Program does not specify a version number of
  247. this License, you may choose any version ever published by the Free Software
  248. Foundation.
  249.  
  250.   10. If you wish to incorporate parts of the Program into other free
  251. programs whose distribution conditions are different, write to the author
  252. to ask for permission.  For software which is copyrighted by the Free
  253. Software Foundation, write to the Free Software Foundation; we sometimes
  254. make exceptions for this.  Our decision will be guided by the two goals
  255. of preserving the free status of all derivatives of our free software and
  256. of promoting the sharing and reuse of software generally.
  257.  
  258.                             NO WARRANTY
  259.  
  260.   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  261. FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  262. OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  263. PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  264. OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  265. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  266. TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  267. PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  268. REPAIR OR CORRECTION.
  269.  
  270.   12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  271. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  272. REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  273. INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  274. OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  275. TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  276. YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  277. PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  278. POSSIBILITY OF SUCH DAMAGES.
  279.  
  280.                      END OF TERMS AND CONDITIONS
  281.  
  282.             How to Apply These Terms to Your New Programs
  283.  
  284.   If you develop a new program, and you want it to be of the greatest
  285. possible use to the public, the best way to achieve this is to make it
  286. free software which everyone can redistribute and change under these terms.
  287.  
  288.   To do so, attach the following notices to the program.  It is safest
  289. to attach them to the start of each source file to most effectively
  290. convey the exclusion of warranty; and each file should have at least
  291. the "copyright" line and a pointer to where the full notice is found.
  292.  
  293.     <one line to give the program's name and a brief idea of what it does.>
  294.     Copyright (C) 19yy  <name of author>
  295.  
  296.     This program is free software; you can redistribute it and/or modify
  297.     it under the terms of the GNU General Public License as published by
  298.     the Free Software Foundation; either version 2 of the License, or
  299.     (at your option) any later version.
  300.  
  301.     This program is distributed in the hope that it will be useful,
  302.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  303.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  304.     GNU General Public License for more details.
  305.  
  306.     You should have received a copy of the GNU General Public License
  307.     along with this program; if not, write to the Free Software
  308.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  309.  
  310.  
  311. Also add information on how to contact you by electronic and paper mail.
  312.  
  313. If the program is interactive, make it output a short notice like this
  314. when it starts in an interactive mode:
  315.  
  316.     Gnomovision version 69, Copyright (C) 19yy name of author
  317.     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  318.     This is free software, and you are welcome to redistribute it
  319.     under certain conditions; type `show c' for details.
  320.  
  321. The hypothetical commands `show w' and `show c' should show the appropriate
  322. parts of the General Public License.  Of course, the commands you use may
  323. be called something other than `show w' and `show c'; they could even be
  324. mouse-clicks or menu items--whatever suits your program.
  325.  
  326. You should also get your employer (if you work as a programmer) or your
  327. school, if any, to sign a "copyright disclaimer" for the program, if
  328. necessary.  Here is a sample; alter the names:
  329.  
  330.   Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  331.   `Gnomovision' (which makes passes at compilers) written by James Hacker.
  332.  
  333.   <signature of Ty Coon>, 1 April 1989
  334.   Ty Coon, President of Vice
  335.  
  336. This General Public License does not permit incorporating your program into
  337. proprietary programs.  If your program is a subroutine library, you may
  338. consider it more useful to permit linking proprietary applications with the
  339. library.  If this is what you want to do, use the GNU Library General
  340. Public License instead of this License. */
  341.  
  342. #include "httpd.h"
  343. #include "http_config.h"
  344. #include "http_request.h"
  345. #include "http_protocol.h"
  346. #include "http_core.h"
  347. #include "http_log.h"
  348.  
  349. #include <time.h>
  350. #include <errno.h>
  351. #include <signal.h>
  352. #include <unistd.h>
  353. #include <sys/time.h>
  354. #include <sys/types.h>
  355. #include <sys/socket.h>
  356. #include <sys/ioctl.h>
  357. #include <netinet/in.h>
  358. #include <arpa/inet.h>
  359. #include <netdb.h>
  360.  
  361. #include "adml.h"
  362.  
  363. #if _TPE_CM > 0
  364.         #include "lib/credit-mutuel/include/cm-mac.h"   /* TPE du credit mutuel */
  365. #endif
  366.  
  367. /* Le debut et fin de tag ne peuvent faire que 2 caracteres precisement */
  368. #define DEBUT_TAG "<*"
  369. #define FIN_TAG "*>"
  370.  
  371. #define FALSE 0
  372. #define TRUE 1
  373. #define FORMAT_DATE_DEFAUT "%A, %d-%b-%Y %H:%M:%S %Z"
  374.  
  375. #define CONFIG_MODE_SERVER 1
  376. #define CONFIG_MODE_DIRECTORY 2
  377. #define CONFIG_MODE_COMBO 3     /* Shouldn't ever happen. */
  378.  
  379. /*--------------------------------------------------------------------------*/
  380. /* Declarations de la structure de donnees.                                 */
  381. /*--------------------------------------------------------------------------*/
  382.  
  383. #define N_FORM 6                /* Nombre de structure Form */
  384. #define N_VAR 6   /* Nombre de structure Var */
  385. #define N_MYSQL 6              /* Nombre de structure Form */
  386. #define N_WHILE 21            /* Nombre de boucle imbrique maximum */
  387. #define N_DATE 6                /* Nombre de structure date */
  388. #define N_UPLOAD 11          /* Nombre maximum de fichier Upload */
  389. #define N_SOCKET 6            /* Nombre maximum de structure socket (la derniere socket n'est utiliser qu'en interne pour les includes par exemple) */
  390. #if _XML_EXPAT > 0
  391.         #define N_XML 6   /* Nombre de structure XML */
  392. #endif
  393.  
  394. #define TAILLE_BUFFER 1024      /* Taille du buffer a alloue dans conf->buffer a la creation du processus */
  395.  
  396. static const long unsigned int crc32table[] = {
  397.     0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
  398.     0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD,
  399.     0x4C11DB70,0x48D0C6C7,0x4593E01E,0x4152FDA9,0x5F15ADAC,0x5BD4B01B,0x569796C2,0x52568B75,
  400.     0x6A1936C8,0x6ED82B7F,0x639B0DA6,0x675A1011,0x791D4014,0x7DDC5DA3,0x709F7B7A,0x745E66CD,
  401.     0x9823B6E0,0x9CE2AB57,0x91A18D8E,0x95609039,0x8B27C03C,0x8FE6DD8B,0x82A5FB52,0x8664E6E5,
  402.     0xBE2B5B58,0xBAEA46EF,0xB7A96036,0xB3687D81,0xAD2F2D84,0xA9EE3033,0xA4AD16EA,0xA06C0B5D,
  403.     0xD4326D90,0xD0F37027,0xDDB056FE,0xD9714B49,0xC7361B4C,0xC3F706FB,0xCEB42022,0xCA753D95,
  404.     0xF23A8028,0xF6FB9D9F,0xFBB8BB46,0xFF79A6F1,0xE13EF6F4,0xE5FFEB43,0xE8BCCD9A,0xEC7DD02D,
  405.     0x34867077,0x30476DC0,0x3D044B19,0x39C556AE,0x278206AB,0x23431B1C,0x2E003DC5,0x2AC12072,
  406.     0x128E9DCF,0x164F8078,0x1B0CA6A1,0x1FCDBB16,0x018AEB13,0x054BF6A4,0x0808D07D,0x0CC9CDCA,
  407.     0x7897AB07,0x7C56B6B0,0x71159069,0x75D48DDE,0x6B93DDDB,0x6F52C06C,0x6211E6B5,0x66D0FB02,
  408.     0x5E9F46BF,0x5A5E5B08,0x571D7DD1,0x53DC6066,0x4D9B3063,0x495A2DD4,0x44190B0D,0x40D816BA,
  409.     0xACA5C697,0xA864DB20,0xA527FDF9,0xA1E6E04E,0xBFA1B04B,0xBB60ADFC,0xB6238B25,0xB2E29692,
  410.     0x8AAD2B2F,0x8E6C3698,0x832F1041,0x87EE0DF6,0x99A95DF3,0x9D684044,0x902B669D,0x94EA7B2A,
  411.     0xE0B41DE7,0xE4750050,0xE9362689,0xEDF73B3E,0xF3B06B3B,0xF771768C,0xFA325055,0xFEF34DE2,
  412.     0xC6BCF05F,0xC27DEDE8,0xCF3ECB31,0xCBFFD686,0xD5B88683,0xD1799B34,0xDC3ABDED,0xD8FBA05A,
  413.     0x690CE0EE,0x6DCDFD59,0x608EDB80,0x644FC637,0x7A089632,0x7EC98B85,0x738AAD5C,0x774BB0EB,
  414.     0x4F040D56,0x4BC510E1,0x46863638,0x42472B8F,0x5C007B8A,0x58C1663D,0x558240E4,0x51435D53,
  415.     0x251D3B9E,0x21DC2629,0x2C9F00F0,0x285E1D47,0x36194D42,0x32D850F5,0x3F9B762C,0x3B5A6B9B,
  416.     0x0315D626,0x07D4CB91,0x0A97ED48,0x0E56F0FF,0x1011A0FA,0x14D0BD4D,0x19939B94,0x1D528623,
  417.     0xF12F560E,0xF5EE4BB9,0xF8AD6D60,0xFC6C70D7,0xE22B20D2,0xE6EA3D65,0xEBA91BBC,0xEF68060B,
  418.     0xD727BBB6,0xD3E6A601,0xDEA580D8,0xDA649D6F,0xC423CD6A,0xC0E2D0DD,0xCDA1F604,0xC960EBB3,
  419.     0xBD3E8D7E,0xB9FF90C9,0xB4BCB610,0xB07DABA7,0xAE3AFBA2,0xAAFBE615,0xA7B8C0CC,0xA379DD7B,
  420.     0x9B3660C6,0x9FF77D71,0x92B45BA8,0x9675461F,0x8832161A,0x8CF30BAD,0x81B02D74,0x857130C3,
  421.     0x5D8A9099,0x594B8D2E,0x5408ABF7,0x50C9B640,0x4E8EE645,0x4A4FFBF2,0x470CDD2B,0x43CDC09C,
  422.     0x7B827D21,0x7F436096,0x7200464F,0x76C15BF8,0x68860BFD,0x6C47164A,0x61043093,0x65C52D24,
  423.     0x119B4BE9,0x155A565E,0x18197087,0x1CD86D30,0x029F3D35,0x065E2082,0x0B1D065B,0x0FDC1BEC,
  424.     0x3793A651,0x3352BBE6,0x3E119D3F,0x3AD08088,0x2497D08D,0x2056CD3A,0x2D15EBE3,0x29D4F654,
  425.     0xC5A92679,0xC1683BCE,0xCC2B1D17,0xC8EA00A0,0xD6AD50A5,0xD26C4D12,0xDF2F6BCB,0xDBEE767C,
  426.     0xE3A1CBC1,0xE760D676,0xEA23F0AF,0xEEE2ED18,0xF0A5BD1D,0xF464A0AA,0xF9278673,0xFDE69BC4,
  427.     0x89B8FD09,0x8D79E0BE,0x803AC667,0x84FBDBD0,0x9ABC8BD5,0x9E7D9662,0x933EB0BB,0x97FFAD0C,
  428.     0xAFB010B1,0xAB710D06,0xA6322BDF,0xA2F33668,0xBCB4666D,0xB8757BDA,0xB5365D03,0xB1F740B4
  429. };
  430.  
  431. static char base64table[] = {
  432.         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
  433.         'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
  434.         'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
  435.         'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
  436. };
  437. static char base64pad = '=';
  438.  
  439. static unsigned char hexa[] = "0123456789ABCDEF";
  440.  
  441. static const char *code_html[] = {"nbsp","iexcl","cent","pound","curren","yen","brkbar",
  442. "sect","uml","copy","ordf","laquo","not","shy","reg","macr","deg","plusm",
  443. "sup2","sup3","acute","micro","para","middot","cedil","sup1","ordm","raquo",
  444. "frac14","frac12","frac34","iquest","Agrave","Aacute","Acirc","Atilde","Auml",
  445. "Aring","AElig","Ccedil","Egrave","Eacute","Ecirc","Euml","Igrave","Iacute",
  446. "Icirc","Iuml","Dstrok","Ntilde","Ograve","Oacute","Ocirc","Otilde","Ouml",
  447. "times","Oslash","Ugrave","Uacute","Ucirc","Uuml","Yacute","THORN","szlig",
  448. "agrave","aacute","acirc","atilde","auml","aring","aelig","ccedil","egrave",
  449. "eacute","ecirc","euml","igrave","iacute","icirc","iuml","eth","ntilde",
  450. "ograve","oacute","ocirc","otilde","ouml","divide","oslash","ugrave","uacute",
  451. "ucirc","uuml","yacute","thorn","yuml", NULL};
  452.  
  453. static int jour_dans_mois[2][13] = {
  454.         {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  455.         {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
  456. };
  457.  
  458. static const char *jour[6][7] = {
  459.         {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"},                  /* -- Francais -- */
  460.         {"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"},
  461.         {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},  /* -- Anglais -- */
  462.         {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"},
  463.         {"Sontag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"},       /* -- Allemand -- */
  464.         {"Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"}
  465. };
  466.  
  467. static const char *mois[6][12] = {
  468.         {"Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"},        /* -- francais -- */
  469.         {"Jan", "Fév", "Mar", "Avr", "Mai", "Jun", "Jui", "Aou", "Sep", "Oct", "Nov", "Déc"},
  470.         {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"},          /* -- Anglais -- */
  471.         {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"},
  472.         {"Januar", "Februar", "Marz", "April", "Mai", "Juny", "July", "August", "September", "October", "November", "December"},                /* -- Allemand -- */
  473.         {"Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
  474. };
  475.  
  476. #define JEUDI           4               /* pour reformation */
  477. #define SAMEDI          6               /* le 1 Jan 1 est un Samedi */
  478.  
  479. #define FIRST_MISSING_DAY       639787          /* 3 Sep 1752 */
  480. #define NUMBER_MISSING_DAYS     11              /* 11 day correction */
  481.  
  482. /* annee bissextile - 0: pas bissextile, 1: annee bisextile */
  483. #define annee_bissex(annee) \
  484.         ((annee) <= 1752 ? !((annee) % 4) : \
  485.         (!((annee) % 4) && ((annee) % 100)) || !((annee) % 400))
  486.  
  487. /* nombre de siecles depuis 1700, non inclut */
  488. #define siecles_depuis_1700(annee) \
  489.         ((annee) > 1700 ? (annee) / 100 - 17 : 0)
  490.  
  491. /* nombre de 4 siecles depuis 1700 */
  492. #define quatre_siecles_depuis_1700(annee) \
  493.         ((annee) > 1600 ? ((annee) - 1600) / 400 : 0)
  494.  
  495. /* nombre d'annee bissextile entre l'annee 1 et cette annee, non inclut */
  496. #define nombre_annee_bissex(annee) \
  497.         ((annee) / 4 - siecles_depuis_1700(annee) + quatre_siecles_depuis_1700(annee))
  498.  
  499. #define if_sortie (conf->ifwhile[conf->nwhile].sortie && conf->show)
  500.  
  501. /* ---------- Structure pour Upload ---------- */
  502. typedef struct adml_upload {
  503.         char *remote_filename;
  504.         char *filename;
  505.         char *content_type;
  506.         char *name;
  507.         char *data;
  508.         char *save;     /* NULL si pas sauvegarde et nom du fichier de la derniere sauvegarde sinon */
  509.         unsigned long int taille;
  510. } adml_upload;
  511.  
  512. /* ---------- Structure pour Mime ---------- */
  513. typedef struct adml_mime {
  514.         char *buffer;
  515.         unsigned long int taille;
  516.         unsigned long int position;
  517.         const char *boundary;
  518.         char *content_type;
  519.         char *content_disposition;
  520.         char *content_transfer_encoding;
  521.         char *data;
  522.         unsigned long int taille_data;
  523.         int fin;        /* Afin de renvoyer un TRUE si le boundary de fin a ete trouve et FALSE si non */
  524. } adml_mime;
  525.  
  526. /* ---------- Structure pour Form ---------- */
  527. typedef struct adml_form {
  528.         table *tab;     /* Table pour la liste de champs */
  529.         int pos;                /* Position courante sur la liste de champs */
  530. } adml_form;
  531.  
  532. /* ---------- Structure pour Var ---------- */
  533. typedef struct adml_var {
  534.         table *tab;     /* Table pour la liste de champs */
  535.         int pos;                /* Position courante sur la liste de champs */
  536. } adml_var;
  537.  
  538.  
  539. /* ---------- Structure pour Cookies ---------- */
  540. typedef struct adml_cookies {
  541.         table *tab;     /* Table pour la liste de champs */
  542.         int pos;                /* Position courante sur la liste de champs */
  543. } adml_cookies;
  544.  
  545. enum socket_flag { NONE=0, NOWAIT=1, FORK=2, NOHANDLE=4 };
  546. /* ---------- Structure pour les Sockets ---------- */
  547. typedef struct adml_socket {
  548.         BUFF *f;
  549.         int fd;
  550.         int port;
  551.         pool *p;
  552.         const char *host;
  553.         const char *service;
  554.         int last_excess;
  555.         char *last_pos;
  556.         char eom;
  557.         table *headers;
  558.         char *buffer;
  559.         int taille_buffer, taille_buffer_max;
  560.         size_t recv_buffer_size;
  561. } adml_socket;
  562.  
  563. /* ---------- Structure pour le SMTP ---------- */
  564. typedef struct adml_smtp {
  565.         adml_socket sock;       /* structure socket pour les envois de E-Mail */
  566.         int code_retour;
  567.         int etrn;
  568.         int dsn;
  569.         int bit8mime;
  570. } adml_smtp;
  571.  
  572. /* ---------- Structure pour Mysql ---------- */
  573. typedef struct adml_mysql {
  574.         int fconnect, fbase, fquery, ferror;
  575.         int numligne, numcolonne;
  576.         MYSQL mysql;        /* Socket */
  577.         MYSQL_RES *res;  /* Structure */
  578.         MYSQL_ROW row;    /* champs */
  579.         MYSQL_FIELD *field;     /* champs */
  580. } adml_mysql;
  581.  
  582. /* ---------- Structure pour les boucles While ---------- */
  583. typedef struct adml_while {
  584.         int type, tour, limite, num;
  585.         int sortie, execute;
  586.         int position;   /* Afin de memorise la position dans le fichier en cour du debut du contenu de la boucle */
  587.         int ligne;      /* Afin de memoriser le numero de ligne au debut de la boucle de facon que la boucle ne genere pas d'erreur sur les numeros de lignes */
  588.         array_header *arr;      /* Afin de memoriser si besoin est un pointeur vers un array */
  589. } adml_while;
  590.  
  591. #if _XML_EXPAT > 0
  592.         /* ---------- Structure pour les boucles While ---------- */
  593.         typedef struct adml_xml {
  594.                 int depth;
  595.                 XML_Parser parser;
  596.         } adml_xml;
  597. #endif
  598.  
  599. /* ---------- Structure Generale ---------- */
  600. typedef struct adml_cfg {
  601.         const char *filename;   /* Pour memoriser le nom du fichier include en cour ou NULL si on est dans le fichier principal ou "-VaR!" si ont est dans une variable */
  602.         char *fichier;      /* Pour le fichier principal */
  603.         int ligne;                        /* Numero et position de ligne courante du fichier en cour (utile pour les erreurs) */
  604.         int taille_fichier;          /* Taille du fichier */
  605.         table *tag;                    /* afin de decortiquer un tag proprietaire */
  606.         table *include;   /* afin de memoriser les fichiers includes */
  607.         char *tag_nom;      /* Nom du tag */
  608.         char *tag_valeur;              /* Valeur du tag */
  609.         int debut_tag;      /* Pointe sur le premier caractere du tag courrant */
  610.         int fin_tag;            /* Pointe sur le dernier caractere du tag courrant */
  611.         int pos_fichier;                /* Position du pointeur d'analyse du fichier */
  612.         pool *pool_tag;   /* pool pour l'analyse des tags (Initialiser a chaque debut de TAG) */
  613.         pool *pool_session;          /* pool pour la creation des structures form par exemple (initialise a chaque session) */
  614.         char *temp, *temp1;          /* Pour usage temporaire */
  615.         const char *ctemp;            /* Pour usage temporaire */
  616.         long engine;            /* Pour la commande : ModelEngine on|off */
  617.         double calcul;      /* Principalement pour la fonction calcul afin qu'elle puissent passer des resultat en numerique */
  618.         adml_form form[N_FORM]/* Structures Form */
  619.         adml_var var[N_VAR];    /* Structures Var */
  620.         int form_def;         /* Numero de structure par defaut de Form */
  621.         int var_def;            /* Numero de structure par defaut de Var */
  622.         adml_mysql base_mysql[N_MYSQL]/* Structure mysql */
  623.         int mysql_def;      /* Numero de structure par defaut de Mysql */
  624.         adml_socket sock[N_SOCKET + 1]/* structures socket */
  625.         adml_smtp smtp;   /* structure socket pour les envois de E-Mail */
  626.         char *mysql_host;              /* Pour la config par defaut */
  627.         char *mysql_user;              /* Pour la config par defaut */
  628.         char *mysql_passwd;          /* Pour la config par defaut */
  629.         char *mysql_base;              /* Pour la config par defaut */
  630.         int nwhile;     /* Pour connaitre le niveau d'imbriction */
  631.         adml_while ifwhile[N_WHILE];    /* Pour les boucle While et les IF */
  632.         time_t secs[N_DATE];    /* structure Date */
  633.         int notagbr;            /* SI il est a TRUE, alors les retour chariot juste apres un TAG proprietaire sont supprimmer */
  634.         const char *unique_id;  /* Identificateur unique pour la session en cour et ses sous-requetes */
  635.         char *boundary;   /* Pour stocker le boundary du multipart/form-data */
  636.         adml_upload upload[N_UPLOAD];   /* Structure pour stocker les uploads */
  637.         int nupload;            /* Afin de savoir combien de upload sont stocker dans la structure upload */
  638.         int upload_num;   /* position courante dans la structure upload */
  639.         request_rec *rr;                /* Afin de realiser une sous-requete */
  640.         request_rec *r;   /* Afin de garder la trace dans la structure de la requete */
  641.         int header, noheader;   /* header=TRUE si le Header est deja envoye et noheader=TRUE si le header ne doit pas etre envoye */
  642.         int exit;                            /* TRUE si une commande EXIT a ete utilise (donc sortie de la page) */
  643.         char buffer[TAILLE_BUFFER + 1];  /* Buffer de taille TAILLE_BUFFER alloue a la creation du processus */
  644.         adml_cookies cookies;   /* Structure devant contenir la liste des cookies */
  645.         int headers_in_num;          /* Position courante dans la table des headers_in */
  646.         const char *auth_user, *auth_passwd, *auth_type;        /* Pour l'entete Authorization: (si user == NULL, c'est qu'il n'y a rien) */
  647.         int show;                            /* Pour le tag Show= On ou Off */
  648. #if _XML_EXPAT > 0
  649.         adml_xml xml[N_XML];    /* Structure XML */
  650. #endif
  651. } adml_cfg;
  652.  
  653. typedef struct adml_calcul {
  654.         int type;
  655.         char *chaine;
  656.         double valeur;
  657. } adml_calcul;
  658.  
  659. /*
  660. * Let's set up a module-local static cell to point to the accreting callback
  661. * trace.  As each API callback is made to us, we'll tack on the particulars
  662. * to whatever we've already recorded.  To avoid massive memory bloat as
  663. * directories are walked again and again, we record the routine/environment
  664. * the first time (non-request context only), and ignore subsequent calls for
  665. * the same routine/environment.
  666. */
  667. static const char *trace = NULL;
  668.  
  669. /* Declaration du module */
  670. module adml_module;
  671.  
  672. static char *int_to_hex(pool *p, long unsigned int val, int digit, char *result);
  673. static int add_form(table *form, const char *nom, const char *valeur, int type);
  674. static void decode_classique(adml_cfg *conf, int num, char *chaine, int type, int copie);
  675. static double calc(adml_cfg *conf, const char *chaine);
  676. static char *interp(adml_cfg *conf, const char *chaine);
  677. static void analyse_page(request_rec *r, char *fichier);
  678. static int recup(request_rec *r);
  679. static void recup_cookies(adml_cfg *conf);
  680. static int testlog(adml_cfg *conf, const char *chaine);
  681. static int isnum(const char *chaine);
  682.  
  683. /*--------------------------------------------------------------------------*/
  684. /* Prend en compte les parametres de type FLAG (on/off)                     */
  685. /*--------------------------------------------------------------------------*/
  686. static const char *handle_FLAG(cmd_parms *cmd, adml_cfg *conf, int val)
  687. {
  688.         int i = (int)cmd->info; /* recupere le parametre supplementaire */
  689.  
  690.         switch(i)
  691.         {
  692.         case 0:    /* Commande : AdmlEngine on|off */
  693.                 conf->engine = val;
  694.                 break;
  695.         }
  696.         return NULL;
  697. }
  698.  
  699. /*--------------------------------------------------------------------------*/
  700. /* Prend en compte les parametres avec 1 argument                           */
  701. /*--------------------------------------------------------------------------*/
  702. static const char *handle_TAKE1(cmd_parms *cmd, adml_cfg *conf, char *argument)
  703. {
  704.         int i = (int)cmd->info; /* recupere le parametre supplementaire */
  705.  
  706.         switch(i)
  707.         {
  708.         case 0:  /* Commande : MysqlHost */
  709.                 conf->mysql_host = argument;
  710.                 break;
  711.         case 1:  /* Commande : MysqlUser */
  712.                 conf->mysql_user = argument;
  713.                 break;
  714.         case 2:  /* Commande : MysqlPassword */
  715.                 conf->mysql_passwd = argument;
  716.                 break;
  717.         case 3:  /* Commande : MysqlBase */
  718.                 conf->mysql_base = argument;
  719.                 break;
  720.         }
  721.         return NULL;
  722. }
  723.  
  724. /*--------------------------------------------------------------------------*/
  725. /* Encodage Base64                                                          */
  726. /*--------------------------------------------------------------------------*/
  727. static unsigned char *base64encode(pool *p, const unsigned char *chaine, int taille, int *res_taille)
  728. {
  729.         const unsigned char *ptr = chaine;
  730.         int i = 0;
  731.         unsigned char *result = (unsigned char *)ap_palloc(p, ((taille + 3 - taille % 3) * 4 / 3 + 1) * sizeof(char))/* Alloue la zone memoire necessaire a l'encodage */
  732.  
  733.         /* keep going until we have less than 24 bits */
  734.         while (taille > 2)
  735.         {
  736.                 result[i++] = base64table[ptr[0] >> 2];
  737.                 result[i++] = base64table[((ptr[0] & 0x03) << 4) + (ptr[1] >> 4)];
  738.                 result[i++] = base64table[((ptr[1] & 0x0f) << 2) + (ptr[2] >> 6)];
  739.                 result[i++] = base64table[ptr[2] & 0x3f];
  740.  
  741.                 ptr += 3;
  742.                 taille -= 3;
  743.         }
  744.  
  745.         /* now deal with the tail end of things */
  746.         if (taille != 0)
  747.         {
  748.                 result[i++] = base64table[ptr[0] >> 2];
  749.                 if (taille > 1)
  750.                 {
  751.                         result[i++] = base64table[((ptr[0] & 0x03) << 4) + (ptr[1] >> 4)];
  752.                         result[i++] = base64table[(ptr[1] & 0x0f) << 2];
  753.                         result[i++] = base64pad;
  754.                 }
  755.         else
  756.                 {
  757.                         result[i++] = base64table[(ptr[0] & 0x03) << 4];
  758.                         result[i++] = base64pad;
  759.                         result[i++] = base64pad;
  760.                 }
  761.         }
  762.  
  763.         if(res_taille) *res_taille = i; /* retourne la taille si le pointeur res_taille n'est pas NULL */
  764.  
  765.         result[i] = '\0';       /* Fin de chaine */
  766.         return(result);
  767. }
  768.  
  769. /*--------------------------------------------------------------------------*/
  770. /* Decodage Base64                                                          */
  771. /* Retourne la chaine decoder ou NULL si pas possible ou erreur             */
  772. /*--------------------------------------------------------------------------*/
  773. static unsigned char *base64decode(pool *p, const unsigned char *chaine, int taille, int *res_taille)
  774. {
  775.         const unsigned char *ptr = chaine;
  776.         int ch, i = 0, j = 0;
  777.  
  778.         unsigned char *result = (unsigned char *)ap_palloc(p, (taille / 4 * 3 + 1) * sizeof(char));     /* alloue la zone memoire necessaire au decodage */
  779.         if (result == NULL) return(NULL);
  780.  
  781.         while ((ch = *ptr++) != '\0')   /* Boucle pour traitement de conversion */
  782.         {
  783.                 if (ch == base64pad) break;
  784.                 ch = (int)strchr(base64table, ch);
  785.                 if (ch == 0) return(NULL);
  786.                 ch -= (int)base64table;
  787.  
  788.                 switch(i % 4)
  789.                 {
  790.                         case 0:
  791.                                 result[j] = ch << 2;
  792.                                 break;
  793.                         case 1:
  794.                                 result[j++] |= ch >> 4;
  795.                                 result[j] = (ch & 0x0f) << 4;
  796.                                 break;
  797.                         case 2:
  798.                                 result[j++] |= ch >>2;
  799.                                 result[j] = (ch & 0x03) << 6;
  800.                                 break;
  801.                         case 3:
  802.                                 result[j++] |= ch;
  803.                                 break;
  804.                 }
  805.                 i++;
  806.         }
  807.  
  808.         if (ch == base64pad)    /* Si c'est la fin de la chaine encode */
  809.         {
  810.                 switch(i % 4)
  811.                 {
  812.                         case 0:
  813.                         case 1:
  814.                                 return(NULL);
  815.                         case 2:
  816.                                 j++;
  817.                         case 3:
  818.                                 result[j++] = 0;
  819.                 }
  820.         }
  821.         if(res_taille) *res_taille = j; /* retourne la taille du resultat si res_taille est different de NULL */
  822.  
  823.         result[j] = '\0';       /* fin de chaine */
  824.         return(result);
  825. }
  826.  
  827. /*--------------------------------------------------------------------------*/
  828. /* Si quot = TRUE, alors prend en compte les guillemets dans la chaine      */
  829. /* Retourne NULL si pas trouve et le mot si trouve                          */
  830. /* Type : 0 = renvoi un char avec le mot recuperer ou NULL si pas trouve    */
  831. /*        1 = renvoi un int avec TRUE si le mot existe ou FALSE sinon       */
  832. /*        2 = retoune un int avec le nombre de mots de la chaine            */
  833. /* ret est le pointeur de la variable a retourner pour le int               */
  834. /*--------------------------------------------------------------------------*/
  835. static void *recupmots(pool *p, const char *chaine, int num, int min, int max, int quot, int type, int *ret)
  836. {
  837.         int guil = FALSE;       /* Pas encore de guillemet d'ouvert */
  838.         int flag = FALSE;       /* Ont est pas encore dans un mot */
  839.         int pos, z = 0, x = -1;
  840.  
  841.         if (min < 1) min = 1;   /* La taille minimum ne doit pas etre inferieur a 1 */
  842.         if (max < 0) max = 0;   /* La taille maximum ne doit pas etre negative */
  843.  
  844.         if (num > 0)    /* C'est pas la peine de chercher si num < 1 */
  845.         {
  846.                 while(chaine[++x] != '\0')
  847.                 {
  848.                         if (flag)       /* Je suis dans un mot */
  849.                         {
  850.                                 if ((!guil && (chaine[x] < 48 || (chaine[x] >57 && chaine[x] < 64))) || (guil && chaine[x] == '\"'))        /* Fin du mot */
  851.                                 {
  852.                                         flag = FALSE;
  853.                                         guil = FALSE;
  854.                                         if ((x-pos >= min || min < 1) && (x-pos <= max || max < 1)) z++;        /* Mot suivant seulement si il a le nombre de caractere correct */
  855.                                         if (type != 2 && z == num) break;              /* Le mot est trouver */
  856.                                 }
  857.                         }
  858.                         else if ((chaine[x] > 47 && chaine[x] < 58) || chaine[x] > 63 || (chaine[x] == '\"' && quot))   /* J'entre dans un nouveau mot */
  859.                         {
  860.                                 flag = TRUE;
  861.                                 pos = x;        /* debut du mot suivant */
  862.                                 if (chaine[x] == '\"')  /* Si un guillemet a ete ouvert */
  863.                                 {
  864.                                         if (strchr(&chaine[x+1], '\"') == NULL) flag = FALSE;   /* Si il n'y a pas d'autre guillemet plus loin pour ferme alors ignore le guillemet */
  865.                                         else
  866.                                         {
  867.                                                 guil = TRUE;
  868.                                                 pos++;  /* saute le guillemet */
  869.                                         }
  870.                                 }
  871.                         }
  872.                 }
  873.                 if (flag && x-pos > 0 && (x-pos >= min || min < 1) && (x-pos <= max || max < 1)) z++;   /* Si il y a un dernier mot a prendre en compte */
  874.  
  875.                 if (z > 0 && z == num)  /* Si ont a trouve */
  876.                 {
  877.                         if (type == 0) return(ap_pstrndup(p, &chaine[pos], x - pos));
  878.                         else if (type == 1)
  879.                         {
  880.                                 *ret = TRUE;
  881.                                 return(ret);
  882.                         }
  883.                 }
  884.                 else if (type == 2)
  885.                 {
  886.                         *ret = z;       /* Nombre de mots trouve */
  887.                         return(ret);
  888.                 }
  889.         }
  890.  
  891.         /* Si pas trouve */
  892.         if (type == 0) return(NULL);
  893.         else
  894.         {
  895.                 if (type == 1) *ret = FALSE;
  896.                 else if (type == 2) *ret = 0;
  897.  
  898.                 return(ret);
  899.         }
  900. }
  901.  
  902. /*--------------------------------------------------------------------------*/
  903. /* Meme Fonction que l'API Apache mais avec difference Maj/Min ou non       */
  904. /* Si minmaj = TRUE, alors ne tient pas compte des Maj/min                  */
  905. /*--------------------------------------------------------------------------*/
  906. void adml_table_merge(table *t, const char *key, const char *val, int minmaj)
  907. {
  908.         array_header *arr = ap_table_elts(t);
  909.         table_entry *elts = (table_entry *) arr->elts;
  910.         int i;
  911.  
  912.         for (i = 0; i < arr->nelts; ++i)
  913.         {
  914.                 if ((minmaj && !strcasecmp(elts[i].key, key)) || (!minmaj && !strcmp(elts[i].key, key)))
  915.                 {
  916.                         elts[i].val = ap_pstrcat(arr->pool, elts[i].val, ", ", val, NULL);
  917.                         return;
  918.                 }
  919.         }
  920.  
  921.         if (&arr->nelts == &arr->nalloc) fprintf(stderr, "adml_table_merge: table created by X hit limit of %u\n", arr->nalloc);
  922.         elts = (table_entry *) ap_push_array(arr);
  923.  
  924.         elts->key = ap_pstrdup(arr->pool, key);
  925.         elts->val = ap_pstrdup(arr->pool, val);
  926. }
  927.  
  928. /*--------------------------------------------------------------------------*/
  929. /* Meme Fonction que l'API Apache mais avec difference Maj/Min ou non       */
  930. /* Si minmaj = TRUE, alors ne tient pas compte des Maj/min                  */
  931. /*--------------------------------------------------------------------------*/
  932. void adml_table_set(table *t, const char *key, const char *val, int minmaj)
  933. {
  934.         register int i, j, k;
  935.         array_header *arr = ap_table_elts(t);
  936.         table_entry *elts = (table_entry *) arr->elts;
  937.         int done = 0;
  938.  
  939.         for (i = 0; i < arr->nelts; )
  940.         {
  941.                 if ((minmaj && !strcasecmp(elts[i].key, key)) || (!minmaj && !strcmp(elts[i].key, key)))
  942.                 {
  943.                         if (!done)
  944.                         {
  945.                                 elts[i].val = ap_pstrdup(arr->pool, val);
  946.                                 done = 1;
  947.                                 ++i;
  948.                         }
  949.                         else      /* delete an extraneous element */
  950.                         {
  951.                                 for (j = i, k = i + 1; k < arr->nelts; ++j, ++k)
  952.                                 {
  953.                                         elts[j].key = elts[k].key;
  954.                                         elts[j].val = elts[k].val;
  955.                                 }
  956.                                 --arr->nelts;
  957.                         }
  958.                 }
  959.                 else ++i;
  960.         }
  961.  
  962.         if (!done)
  963.         {
  964.                 if (&arr->nelts == &arr->nalloc) fprintf(stderr, "adml_table_add: table created by X hit limit of %u\n", arr->nalloc);
  965.                 elts = (table_entry *) ap_push_array(arr);
  966.  
  967.                 elts->key = ap_pstrdup(arr->pool, key);
  968.                 elts->val = ap_pstrdup(arr->pool, val);
  969.         }
  970. }
  971.  
  972. /*--------------------------------------------------------------------------*/
  973. /* Type = 0:normal 1:is 2:name 3:len 4:pos 5:bool 6:int 7:num               */
  974. /* min_maj = TRUE alors ne tient pas compte de la difference Min/Maj        */
  975. /* pos = position courante                                                  */
  976. /* nbr = selectionne le nbr champ correspondant                             */
  977. /*--------------------------------------------------------------------------*/
  978. static char *cherche_table(adml_cfg *conf, table *tab, int pos, int nbr, const char *chaine, int type, int min_maj)
  979. {
  980.         array_header *arr = ap_table_elts(tab);
  981.         table_entry *elts = (table_entry *) arr->elts;
  982.         int y, w, z = -1, i;
  983.         char *result = "", *ptr;
  984.  
  985.         if (chaine == NULL) return(NULL);
  986.  
  987.         if (!strcasecmp(chaine, "_nbr")) result = ap_psprintf(conf->pool_tag, "%d", arr->nelts);        /* Nombre de champs dans la structure */
  988.         else if (!strncasecmp(chaine, "_pos", 4)) result = ap_psprintf(conf->pool_tag, "%d", pos);      /* position courante */
  989.         else
  990.         {
  991.                 if (chaine[0] != '#')   /* Recherche en nom */
  992.                 {
  993.                         for(y=0, w=0; y < arr->nelts; y++)
  994.                         {
  995.                                 if ((min_maj && !ap_strcasecmp_match(elts[y].key, chaine)) || (!min_maj && !ap_strcmp_match(elts[y].key, chaine)))
  996.                                 {
  997.                                         if (++w == nbr) /* Pour le deuxieme parametre (nbr de champ) */
  998.                                         {
  999.                                                 z = y;
  1000.                                                 break;
  1001.                                         }
  1002.                                 }
  1003.                         }
  1004.                 }
  1005.                 else if (!strcmp(chaine, "#"))  /* Position courante */
  1006.                 {
  1007.                         if (pos >= 0 && pos < arr->nelts) z = pos;      /* Trouver */
  1008.                 }
  1009.                 else if (isnum(&chaine[1]) && strlen(&chaine[1]) > 0)   /* Recherche avec le numero du champ */
  1010.                 {
  1011.                         i = atoi(&chaine[1]);
  1012.                         if (i >= 0 && i < arr->nelts) z = i;    /* Trouver */
  1013.                 }
  1014.  
  1015.                 if (z < 0)
  1016.                 {
  1017.                         if (type == 1 || (type > 4 && type < 9)) result = "0"/* Pour le IS, IF, Bool, Int et Num */
  1018.                 }
  1019.                 else
  1020.                 {
  1021.                         if (type == 1) result = "1";    /* Pour le IS ou IF */
  1022.                         else if (type == 2) result = elts[z].key;       /* Renvoi le nom du champ */
  1023.                         else if (type == 3) result = ap_psprintf(conf->pool_tag, "%lu", (unsigned long int)strlen(elts[z].val));        /* Renvoi la taille du champ */
  1024.                         else if (type == 4) result = ap_psprintf(conf->pool_tag, "%d", z);      /* Renvoi la position du champ */
  1025.                         else if (type == 5)     /* Type BOOL */
  1026.                         {
  1027.                                 if (atoi(elts[z].val)) result = "1";    /* VRAI */
  1028.                                 else result = "0";      /* FAUX */
  1029.                         }
  1030.                         else if (type == 6)     /* TYPE INT */
  1031.                         {
  1032.                                 result = ap_pstrdup(conf->pool_tag, elts[z].val);
  1033.                                 if ((ptr = strchr(result, ',')) != NULL) ptr[0] = '.';     /* Remplacer la virgule par un point pour que atof() convertisse correctement */
  1034.                                 result = ap_psprintf(conf->pool_tag, "%0.0lf", atof(result));
  1035.                         }
  1036.                         else result = elts[z].val;      /* Renvoi la valeur du champ correspondant au numero */
  1037.                 }
  1038.         }
  1039.  
  1040.         return(result);
  1041. }
  1042.  
  1043. /*--------------------------------------------------------------------------*/
  1044. /* GET_PORT                                                                 */
  1045. /*--------------------------------------------------------------------------*/
  1046. static int get_port(const char *service)
  1047. {
  1048.         struct servent *servent;
  1049.  
  1050.         if (!service || !strlen(service)) return(-1);   /* Le service n'existe pas */
  1051.  
  1052.         if (!isdigit(*service))
  1053.         {
  1054.                 if ((servent = getservbyname((char *)service, "tcp")) == 0) return(-1)/* Err */
  1055.         }
  1056.         else
  1057.         {
  1058.                 if ((servent = getservbyport(atoi(service), "tcp")) == 0) return(htons(atoi(service)));
  1059.         }
  1060.  
  1061.         return(servent->s_port);
  1062. }
  1063.  
  1064. /*--------------------------------------------------------------------------*/
  1065. /* GET_IP                                                                   */
  1066. /*--------------------------------------------------------------------------*/
  1067. static unsigned long get_ip(const char *host)
  1068. {
  1069.         struct hostent *hostent;
  1070.         struct in_addr *addr;
  1071.         unsigned long addr1;
  1072.  
  1073.         if (!host || !strlen(host)) return(-1)/* pas de host */
  1074.  
  1075.         if (!isdigit(*host))
  1076.         {
  1077.                 if ((hostent = gethostbyname((char *)host)) == 0) return(-1);
  1078.         }
  1079.         else
  1080.         {
  1081.                 addr1 = inet_addr((char *)host);
  1082.                 return(addr1);
  1083.         }
  1084.  
  1085.         addr = (struct in_addr *) *(hostent->h_addr_list);
  1086.  
  1087.         return(addr[0].s_addr);
  1088. }
  1089.  
  1090. /*--------------------------------------------------------------------------*/
  1091. /* Ferme une connection socket                                              */
  1092. /*--------------------------------------------------------------------------*/
  1093. static int socket_close(adml_socket *sock)
  1094. {
  1095.         if (sock->fd > -1)
  1096.         {
  1097.                 ap_bclose(sock->f);     /* Ferme le flux */
  1098.                 shutdown(sock->fd, 2);
  1099.                 if (!sock->p) ap_pclosesocket(sock->p, sock->fd);
  1100.                 sock->fd = -1;
  1101.         }
  1102.  
  1103.         return(TRUE);
  1104. }
  1105.  
  1106. /*--------------------------------------------------------------------------*/
  1107. /*                                                                          */
  1108. /*--------------------------------------------------------------------------*/
  1109. static int socket_wait(adml_socket *sock, long seconds, long microseconds, int type)
  1110. {
  1111.         int nbytes;
  1112.         const char *src;
  1113.         struct timeval timeval = {seconds, microseconds};
  1114.         fd_set read_fds;
  1115.         fd_set error_fds;
  1116.         fd_set write_fds;
  1117.  
  1118.         if (sock->fd < 0) return(0);    /* Pas de socket connecter */
  1119.  
  1120.         if ((type&1) && (sock->last_excess > 0))
  1121.         {
  1122.                 nbytes = sock->last_excess;
  1123.                 src = sock->last_pos;
  1124.  
  1125.                 while (nbytes-- > 0)
  1126.                 {
  1127.                         if (*src++ == sock->eom) return(1);
  1128.                 }
  1129.         }
  1130.  
  1131.         FD_ZERO(&read_fds);
  1132.         FD_SET(sock->fd, &read_fds);
  1133.  
  1134.         return(select(FD_SETSIZE, (type&1?&read_fds:0), (type&2?&write_fds:0), (type&4?&error_fds:0), (seconds < 0 ? 0 : &timeval)));
  1135. }
  1136.  
  1137. /*--------------------------------------------------------------------------*/
  1138. /* Ecriture de donnees vers une socket                                      */
  1139. /*--------------------------------------------------------------------------*/
  1140. static int socket_write(adml_socket *sock, const char *buffer, int nbytes)
  1141. {
  1142.         const char *ptr = buffer;
  1143.         int len;
  1144.         int wbytes = 0;
  1145.  
  1146. loop_write:
  1147.  
  1148.         if ((len = send(sock->fd, ptr, nbytes, 0)) < 0)
  1149.         {
  1150.                 if ((errno != EWOULDBLOCK) && (errno != EINTR)) return(-errno);
  1151.         }
  1152.  
  1153.         wbytes += len;
  1154.  
  1155.         if (len < nbytes)
  1156.         {
  1157.                 ptr += len;
  1158.                 nbytes -= len;
  1159.                 socket_wait(sock, -1, 0, 2);    /* Wait for socket to be writable */
  1160.                 goto loop_write;
  1161.         }
  1162.  
  1163.         return(wbytes);
  1164. }
  1165.  
  1166. /*--------------------------------------------------------------------------*/
  1167. /* Lecture de donnees en provenance d'une socket                            */
  1168. /*--------------------------------------------------------------------------*/
  1169. static int socket_readmsg(request_rec *r, adml_socket *sock, char *buffer, int nbytes)
  1170. {
  1171.         int len;
  1172.  
  1173.         ap_hard_timeout("ADML Socket Reading...", r);
  1174.         len = ap_bgets(buffer, nbytes, sock->f);
  1175.         if (len == -1 || len == 0)
  1176.         {
  1177.                 /* ap_bclose(sock->f); */
  1178.                 ap_kill_timeout(r);
  1179.                 buffer[0] = 0/* Fin de chaine */
  1180.                 return(len);
  1181.         }
  1182.         ap_kill_timeout(r);
  1183.  
  1184.         buffer[len] = 0;        /* Fin de chaine */
  1185.  
  1186.         return(len);
  1187. }
  1188.  
  1189. /*--------------------------------------------------------------------------*/
  1190. /* Lecture de donnees en provenance d'une socket                            */
  1191. /*--------------------------------------------------------------------------*/
  1192. static int socket_read(request_rec *r, pool *p, adml_socket *sock)
  1193. {
  1194.         char *ptr, *buffer;
  1195.         int len;
  1196.         int nbytes = 1024;
  1197.  
  1198.         buffer = ap_palloc(p, nbytes+1);
  1199.  
  1200. loop_read:
  1201.  
  1202.         if ((len = recv(sock->fd, buffer, nbytes, 0)) < 0)
  1203.         {
  1204.                 if (errno == EINTR) goto loop_read;
  1205.                 else if (errno == EWOULDBLOCK) return(0);
  1206.                 else return(-errno);    /* Erreur */
  1207.         }
  1208.  
  1209. ap_rprintf(r, " [%s] ", buffer);
  1210.  
  1211.         return(len);
  1212. }
  1213.  
  1214. /*--------------------------------------------------------------------------*/
  1215. /* Recupere une ligne dans le buffer socket                                 */
  1216. /* Jusqu'au <LF> en eliminant l'eventuel <CR> precedent le <LF>             */
  1217. /*--------------------------------------------------------------------------*/
  1218. static char *socket_gets(adml_cfg *conf, adml_socket *sock)
  1219. {
  1220.         int z, y;
  1221.         char *temp;
  1222.  
  1223.         z = 0;
  1224.         while((y = socket_readmsg(conf->r, sock, conf->buffer, TAILLE_BUFFER)) > 0)
  1225.         {
  1226.                 if ((z + y) >= sock->taille_buffer_max) /* Si l'emplacement est trop petit */
  1227.                 {
  1228.                         sock->taille_buffer_max += TAILLE_BUFFER;
  1229.                         temp = ap_palloc(sock->p, sizeof(char) * (sock->taille_buffer_max + 1));
  1230.                         memcpy(temp, sock->buffer, sizeof(char) * z);
  1231.                         sock->buffer = temp;
  1232.                 }
  1233.                 memcpy(&sock->buffer[z], conf->buffer, sizeof(char) * y);
  1234.                 z += y;
  1235.                 sock->buffer[z] = '\0'/* Fin de ligne */
  1236.                 if ((temp = strchr(sock->buffer, '\n')) != NULL)        /* Si ont rencontre un caractere de retour chariot */
  1237.                 {
  1238.                         temp[0] = '\0'/* Fin de ligne */
  1239.                         break;
  1240.                 }
  1241.         }
  1242.  
  1243.         return(sock->buffer);
  1244. }
  1245.  
  1246. /*--------------------------------------------------------------------------*/
  1247. /* Envoi une requete SMTP et recupere la reponse dans la structure SMTP     */
  1248. /*--------------------------------------------------------------------------*/
  1249. static int smtp_retour(adml_cfg *conf)
  1250. {
  1251.         char car;
  1252.         conf->smtp.code_retour = 0;
  1253.  
  1254. smtp_req_goto:
  1255.         socket_gets(conf, &conf->smtp.sock);    /* Lecture d'une ligne dans le buffer socket SMTP */
  1256.         if (conf->smtp.sock.buffer[3] == '-') goto smtp_req_goto;
  1257.  
  1258.         if (strlen(conf->smtp.sock.buffer) > 3)
  1259.         {
  1260.                 car = conf->smtp.sock.buffer[3];
  1261.                 conf->smtp.sock.buffer[3] = '\0';
  1262.                 conf->smtp.code_retour = atoi(conf->smtp.sock.buffer);
  1263.                 conf->smtp.sock.buffer[3] = car;
  1264.         }
  1265.  
  1266.         if (conf->smtp.code_retour == 250)
  1267.         {
  1268.                 if (!strncasecmp(&conf->smtp.sock.buffer[4], "ETRN", 4)) conf->smtp.etrn = TRUE;
  1269.                 else if (!strncasecmp(&conf->smtp.sock.buffer[4], "DSN", 3)) conf->smtp.dsn = TRUE;
  1270.                 else if (!strncasecmp(&conf->smtp.sock.buffer[4], "8BITMIME", 8)) conf->smtp.bit8mime = TRUE;
  1271.         }
  1272.  
  1273.         return(conf->smtp.code_retour);
  1274. }
  1275.  
  1276. /*--------------------------------------------------------------------------*/
  1277. /* Realise une connection socket                                            */
  1278. /*--------------------------------------------------------------------------*/
  1279. static int socket_connect(adml_socket *sock, const char *host, const char *service)
  1280. {
  1281.         struct linger linger;
  1282.         int flag, i;
  1283.         struct sockaddr_in remote;
  1284.  
  1285.         socket_close(sock);     /* ferme la socket existante (au cas ou) */
  1286.  
  1287.         ap_clear_pool(sock->p)/* Effacer le contenu du pool (donnees de la precedente socket) */
  1288.         ap_make_table(sock->p, 1);      /* creation de la table des headers */
  1289.         sock->taille_buffer = sock->taille_buffer_max = 0;
  1290.         sock->buffer = "";
  1291.  
  1292.         sock->f = ap_bcreate(sock->p, B_RDWR | B_SOCKET);       /* cree un flux tamponne dans le pool p en lecture et ecriture */
  1293.  
  1294.         if ((sock->fd = ap_psocket(sock->p, PF_INET, SOCK_STREAM, 0)) == -1)
  1295.         {
  1296.                 /* Erreur ERRNO (erreur de connection) */
  1297.                 return(-1);
  1298.         }
  1299.  
  1300.         linger.l_onoff = 1;          /* Specifit que l_linger definit le temp pendant lequel des données non transmise essayeront de l'etre lors d'un close */
  1301.         linger.l_linger = 5;
  1302.         setsockopt(sock->fd, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger));
  1303.  
  1304.         /* Permet de tester qu'une connection sur laquelle aucun transfert n'a ete realise depuis longtemp est encore active et la ferme eventuellement */
  1305.         flag = 1;
  1306.         setsockopt(sock->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&flag, sizeof(int));
  1307.  
  1308.         ap_bpushfd(sock->f, sock->fd, sock->fd);        /* Definit les descripteur de fichier en lecture et ecriture d'un flux */
  1309.  
  1310. /*
  1311.         setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (const char *)&sock->recv_buffer_size, sizeof(int));
  1312. */
  1313.  
  1314.         remote.sin_family = PF_INET;
  1315.         remote.sin_port = get_port(service);
  1316.         remote.sin_addr.s_addr = get_ip(host);
  1317.         sock->port = ntohs(remote.sin_port);
  1318.  
  1319.         do
  1320.         {
  1321.                 i = connect(sock->fd, (struct sockaddr *)&remote, sizeof(remote));
  1322. /*
  1323.                 if (i == SOCKET_ERROR) errno = WSAGetLastError();
  1324. */
  1325.         } while (i == -1 && errno == EINTR);
  1326.  
  1327.         if (i == -1)
  1328.         {
  1329.                 /* Erreur socket */
  1330.                 return(-errno);
  1331.         }
  1332.  
  1333. /*
  1334.         ioctl(sock->fd, FIONBIO, 1);
  1335.         ap_bnonblock(sock->f, B_RD);
  1336. */
  1337.  
  1338.         sock->host = ap_pstrdup(sock->p, host)/* Conserve l'adresse host */
  1339.         sock->service = ap_pstrdup(sock->p, service);   /* Conserve le service */
  1340.  
  1341.         return(sock->fd);
  1342. }
  1343.  
  1344. /*--------------------------------------------------------------------------*/
  1345. /* Imprime un caractere vers le client                                      */
  1346. /*--------------------------------------------------------------------------*/
  1347. static int imprime_char(adml_cfg *conf, int c)
  1348. {
  1349.         if (if_sortie && (conf->noheader || conf->header || c > 32))
  1350.         {
  1351.                 if (!conf->header && !conf->noheader)
  1352.                 {
  1353.                         conf->r->content_type = "text/html";    /* Definit le content_type */
  1354.                         ap_send_http_header(conf->r);
  1355.                         conf->header = TRUE;
  1356.                 }
  1357.                 return(ap_rputc(c, conf->r));
  1358.         }
  1359.  
  1360.         return(0);
  1361. }
  1362.  
  1363. /*--------------------------------------------------------------------------*/
  1364. /* Imprime vers le client                                                   */
  1365. /*--------------------------------------------------------------------------*/
  1366. static int imprime(adml_cfg *conf, const char *fmt, ...)
  1367. {
  1368.         va_list vlist;
  1369.         int n;
  1370.  
  1371.         if (if_sortie)
  1372.         {
  1373.                 if (conf->r->connection->aborted) return(-1);
  1374.  
  1375.                 va_start(vlist, fmt);
  1376.  
  1377.                 if (!conf->header && !conf->noheader)
  1378.                 {
  1379.                         conf->r->content_type = "text/html";    /* Definit le content_type */
  1380.                         ap_send_http_header(conf->r);
  1381.                         conf->header = TRUE;
  1382.                 }
  1383.  
  1384.                 n = ap_vbprintf(conf->r->connection->client, fmt, vlist);
  1385.                 va_end(vlist);
  1386.  
  1387.                 if (n < 0)
  1388.                 {
  1389.                         if (!conf->r->connection->aborted)
  1390.                         {
  1391.                                 ap_log_rerror(APLOG_MARK, APLOG_INFO, conf->r, "client stopped connection before adml imprime() completed");
  1392.                                 ap_bsetflag(conf->r->connection->client, B_EOUT, 1);
  1393.                                 conf->r->connection->aborted = 1;
  1394.                         }
  1395.                         return(-1);
  1396.                 }
  1397.  
  1398.                 do
  1399.                 {
  1400.                         if (conf->r->sent_bodyct) ap_bgetopt(conf->r->connection->client, BO_BYTECT, &conf->r->bytes_sent);
  1401.                 } while (0);
  1402.  
  1403. ap_rflush(conf->r);     /* Vide le tampon vers le client (pour debugage) */
  1404.                 return(n);
  1405.         }
  1406.  
  1407.         return(0);
  1408. }
  1409.  
  1410. /*--------------------------------------------------------------------------*/
  1411. /* Retire les anti-slash d'une chaine                                       */
  1412. /*--------------------------------------------------------------------------*/
  1413. static char *unescape_backslash(char *chaine)
  1414. {
  1415.         int x, y = 0, taille, flag = FALSE;
  1416.  
  1417.         if (chaine == NULL) return(NULL);
  1418.  
  1419.         taille = strlen(chaine);
  1420.  
  1421.         for (x = 0; x < taille; x++)
  1422.         {
  1423.                 if (flag)
  1424.                 {
  1425.                         if (chaine[x] == 'r') chaine[y++] = '\r';
  1426.                         else if (chaine[x] == 'n') chaine[y++] = '\n';
  1427.                         flag = FALSE;
  1428.                 }
  1429.                 else if (chaine[x] == '\\') flag = TRUE;
  1430.                 else chaine[y++] = chaine[x];
  1431.         }
  1432.         chaine[y] = '\0';
  1433.  
  1434.         return(chaine);
  1435. }
  1436.  
  1437. /*--------------------------------------------------------------------------*/
  1438. /* Calcul le CRC32 d'une chaine                                             */
  1439. /*--------------------------------------------------------------------------*/
  1440. static long unsigned int calcul_crc32(const char *chaine)
  1441. {
  1442.         int i, taille;
  1443.         long unsigned int crc32 = 0;
  1444.  
  1445.         if (chaine == NULL) return(0);
  1446.         taille = strlen(chaine);
  1447.  
  1448.         for (i = 0; i < taille; i++) crc32 = (crc32 >> 8) ^ crc32table[(crc32 ^ chaine[i]) & 0xFF];
  1449.  
  1450.         return(crc32);
  1451. }
  1452.  
  1453. /*--------------------------------------------------------------------------*/
  1454. /* Remplace une ou plusieurs occurance d'une sous-chaine dans une chaine    */
  1455. /*--------------------------------------------------------------------------*/
  1456. static char *strrep(pool *p, char *chaine, const char *ch1, const char *ch2, int nbr, int minmaj)
  1457. {
  1458.         int x = -1, y = 0, n = 0, trep, comptage = 0, len;
  1459.         char *result;
  1460.  
  1461.         if ((len = strlen(ch1)) < 1 || nbr == 0) return(chaine);        /* aucun traitement */
  1462.  
  1463.         if ((trep = strlen(ch2)) > len) /* si la chaine de remplacement est plus grande que la sous-chaine a remplacer */
  1464.         {
  1465.                 while(chaine[++x] != '\0')      /* boucle permettant de connaitre le nombre d'occurance afin de calculer la taille de la nouvelle zone memoire a allouer */
  1466.                 {
  1467.                         if ((minmaj && !strncasecmp(&chaine[x], ch1, len)) || (!minmaj && !strncmp(&chaine[x], ch1, len)))
  1468.                         {
  1469.                                 if (++n == nbr || nbr < 0)
  1470.                                 {
  1471.                                         x += len - 1;
  1472.                                         comptage++;     /* Compte le nombre d'occurance */
  1473.                                 }
  1474.                         }
  1475.                 }
  1476.  
  1477.                 if (comptage < 1) return(chaine);       /* s'il y a pas d'occurance de bonne */
  1478.  
  1479.                 result = ap_palloc(p, (strlen(chaine) + (trep * comptage) - (len * comptage) + 1) * sizeof(char));      /* Allocation d'une nouvelle zone memoire */
  1480.         }
  1481.         else result = chaine;
  1482.  
  1483.         x = -1; n = 0; y = 0;
  1484.         while(chaine[++x] != '\0')      /* Boucle de traitement */
  1485.         {
  1486.                 if ((minmaj && !strncasecmp(&chaine[x], ch1, len)) || (!minmaj && !strncmp(&chaine[x], ch1, len)))
  1487.                 {
  1488.                         if (++n == nbr || nbr < 0)
  1489.                         {
  1490.                                 x += len - 1;   /* saute l'occurance */
  1491.                                 strncpy(&result[y], ch2, trep)/* remplace l'occurance */
  1492.                                 y += trep;
  1493.                         }
  1494.                         else result[y++] = chaine[x];
  1495.                 }
  1496.                 else result[y++] = chaine[x];
  1497.         }
  1498.  
  1499.         result[y++] = '\0';
  1500.  
  1501.         return(result);
  1502. }
  1503.  
  1504. /*--------------------------------------------------------------------------*/
  1505. /* Supprim une ou plusieurs occurance d'une sous-chaine dans une chaine     */
  1506. /*--------------------------------------------------------------------------*/
  1507. static char *strsup(char *chaine, const char *sup, int nbr, int minmaj)
  1508. {
  1509.         int x = -1, y = 0, n = 0, len;
  1510.  
  1511.         if ((len = strlen(sup)) < 1 || nbr == 0) return(chaine);        /* aucun traitement */
  1512.  
  1513.         while(chaine[++x] != '\0')
  1514.         {
  1515.                 if ((minmaj && !strncasecmp(&chaine[x], sup, len)) || (!minmaj && !strncmp(&chaine[x], sup, len)))
  1516.                 {
  1517.                         if (++n == nbr || nbr < 0) x += len - 1;
  1518.                         else chaine[y++] = chaine[x];
  1519.                 }
  1520.                 else chaine[y++] = chaine[x];
  1521.         }
  1522.  
  1523.         chaine[y++] = '\0';
  1524.  
  1525.         return(chaine);
  1526. }
  1527.  
  1528. /*--------------------------------------------------------------------------*/
  1529. /* Encode en CRC32 Hexadecimal une chaine                                   */
  1530. /*--------------------------------------------------------------------------*/
  1531. static char *encode_crc32(pool *p, const char *data, const char *key)
  1532. {
  1533.         long unsigned int crc32;
  1534.         int i, tdata, tkey, k = 0, j = 0;
  1535.         char *result;
  1536.         char hex_temp[9];
  1537.  
  1538.         if (data == NULL) data = "";
  1539.         tdata = strlen(data);   /* recupere la taille de la chaine a encoder */
  1540.         crc32 = calcul_crc32(data);     /* Recupere le CRC32 */
  1541.         if (key == NULL) key = int_to_hex(p, crc32, 8, NULL);   /* Si key == NULL alors prend le crc32 en hexa comme cles */
  1542.         tkey = strlen(key);          /* recupere la taille de la cles */
  1543.         result = ap_pcalloc(p, ((tdata * 2) + tkey + 1) * sizeof(char));        /* Alloue l'emplacement memoire */
  1544.  
  1545.         for (i = 0; i < tdata; i++)
  1546.         {
  1547.                 strcpy(&result[k], int_to_hex(p, data[i] ^ key[j], 2, hex_temp));
  1548.                 k += 2;
  1549.                 if (++j >= tkey) j = 0/* Boucle sur la cles */
  1550.         }
  1551.  
  1552.         strcpy(&result[k], int_to_hex(p, crc32, 8, hex_temp))/* Ajoute le CRC32 en hexa a la fin de la chaine */
  1553.  
  1554.         return(result);
  1555. }
  1556.  
  1557. /*--------------------------------------------------------------------------*/
  1558. /* Decode en CRC32 Hexadecimal une chaine                                   */
  1559. /*--------------------------------------------------------------------------*/
  1560. static char *decode_crc32(pool *p, const char *data, const char *key)
  1561. {
  1562.         register char digit;
  1563.         int i, tdata, tkey, x = 0, j = 0;
  1564.         char *result;
  1565.  
  1566.         if (data == NULL) data = "";
  1567.         if ((tdata = strlen(data)) < 9) return(NULL);   /* Erreur */
  1568.         result = ap_pcalloc(p, ((tdata + 2) / 2) * sizeof(char));       /* Alloue l'emplacement memoire */
  1569.         tdata -= 8;
  1570.         if (key == NULL) key = &data[tdata];    /* Si key == NULL alors prend le crc32 comme cles */
  1571.         tkey = strlen(key);
  1572.  
  1573.         for (i = 0; i < tdata; i++)
  1574.         {
  1575.                 digit = (data[i] >= 'A' ? ((data[i] & 0xdf) - 'A')+10 : (data[i] - '0'));
  1576.                 i++;
  1577.                 digit *= 16;
  1578.                 digit += (data[i] >= 'A' ? ((data[i] & 0xdf) - 'A')+10 : (data[i] - '0'));
  1579.                 result[x++] = (digit ^ key[j]);
  1580.                 if (++j >= tkey) j=0;   /* Boucle sur la cles */
  1581.         }
  1582.  
  1583.         if (strcasecmp(&data[tdata], int_to_hex(p, calcul_crc32(result), 8, NULL))) return(NULL);       /* Erreur de CRC */
  1584.  
  1585.         return(result)/* Retourne le resultat du decodage */
  1586. }
  1587.  
  1588. /*--------------------------------------------------------------------------*/
  1589. /* Fonction TRIM (elimine les caractere car devant et derriere)             */
  1590. /*--------------------------------------------------------------------------*/
  1591. static char *trim(char *chaine, const char car)
  1592. {
  1593.         char *ptr;
  1594.         int x = -1;
  1595.  
  1596.         if (chaine == NULL) return(NULL);
  1597.  
  1598.         if (strlen(chaine) > 0)
  1599.         {
  1600.                 while(chaine[++x] == car);
  1601.                 ptr = &chaine[x];       /* Recupere le debut de la chaine */
  1602.  
  1603.                 x = strlen(ptr);
  1604.                 while(ptr[--x] == car);
  1605.                 ptr[++x] = '\0';        /* Fin de chaine */
  1606.                 return(ptr);    /* Retourne le pointeur vers la nouvelle chaine */
  1607.         }
  1608.  
  1609.         return(chaine);
  1610. }
  1611.  
  1612. /*--------------------------------------------------------------------------*/
  1613. /* Algorithme Soundex                                                       */
  1614. /*--------------------------------------------------------------------------*/
  1615. static char *calcul_soundex(pool *p, const char *chaine, int langue)
  1616. {
  1617.         int i, small, len, code, last;
  1618.         char *soundex;
  1619.         char table_soundex[2][26] = {
  1620.                 {0, '1', '2', '3', 0, '9', '7', 0, 0, '7', '2', '4', '5', '5', 0, '1', '2', '6', '8', '3', 0, '9', 0, '8', 0, '8'},     /* Francais */
  1621.                 {0, '1', '2', '3', 0, '1', '2', 0, 0, '2', '2', '4', '5', '5', 0, '1', '2', '6', '2', '3', 0, '1', 0, '2', 0, '2'},     /* Anglais */
  1622.         };
  1623.  
  1624.         if (langue < 0 || langue > 1) langue = 0;
  1625.  
  1626.         soundex = ap_palloc(p, 5);      /* Alloue de la memoire pour le resultat */
  1627.         len = strlen(chaine);
  1628.  
  1629.         last = -1;
  1630.         for (i = 0, small = 0; i < len && small < 4; i++)
  1631.         {
  1632.                 code = chaine[i];
  1633.                 if (code == 224 || code == 225 || code == 226 || code == 227) code = 'A';
  1634.                 else if (code == 232 || code == 233 || code == 234 || code == 'e') code = 'E';
  1635.                 else if (code == 236 || code == 237 || code == 238) code = 'I';
  1636.                 else if (code == 242 || code == 243 || code == 244 || code == 245) code = 'O';
  1637.                 else if (code == 249 || code == 250 || code == 251) code = 'U';
  1638.                 else if (code == 231) code = 'C';
  1639.                 else if (code == 241) code = 'N';
  1640.                 else code = toupper(chaine[i])/* Convertit en majuscule pour que les calculs soit correct */
  1641.  
  1642.                 if (code >= 'A' && code <= 'Z')
  1643.                 {
  1644.                         if (small == 0)
  1645.                         {
  1646.                                 soundex[small++] = code;
  1647.                                 last = table_soundex[langue][code - 'A'];
  1648.                         }
  1649.                         else
  1650.                         {
  1651.                                 code = table_soundex[langue][code - 'A'];
  1652.                                 if (code != last)
  1653.                                 {
  1654.                                         if (code != 0) soundex[small++] = code;
  1655.                                         last = code;
  1656.                                 }
  1657.                         }
  1658.                 }
  1659.         }
  1660.  
  1661.         while(small < 4) soundex[small++] = '0';
  1662.         soundex[small] = '\0';
  1663.  
  1664.         return(soundex);
  1665. }
  1666.  
  1667. /*--------------------------------------------------------------------------*/
  1668. /* 0 = Visa ; 1 = Mastercard ; 2 = American Express ; 3 = Novus             */
  1669. /*--------------------------------------------------------------------------*/
  1670. static int verif_cb(pool *p, int type, const char *numero)
  1671. {
  1672.         int cb[2][16],i=0,x=0;
  1673.         char *nbr;
  1674.  
  1675.         if (numero == NULL) return(FALSE);
  1676.  
  1677.                 i = -1;
  1678.         while(numero[++i] != '\0' && x < 16 && i < 20)
  1679.         {
  1680.                 if ((numero[i] >= '0') && (numero[i] <= '9'))
  1681.                 {
  1682.                         cb[0][x] = (int)numero[i] -48;
  1683.                         if ((cb[1][x] = cb[0][x] *2) > 9) cb[1][x] -= 9;
  1684.                         x++;
  1685.                 }
  1686.         }
  1687.  
  1688.         if (x == 13 && type == 0) i = cb[0][0] + cb[1][1] + cb[0][2] + cb[1][3] + cb[0][4] + cb[1][5] + cb[0][6] + cb[1][7] + cb[0][8] + cb[1][9] + cb[0][10] + cb[1][11] + cb[0][12];
  1689.         else if (x == 16 && (type == 0 || type == 1 || type == 3)) i = cb[1][0] + cb[0][1] + cb[1][2] + cb[0][3] + cb[1][4] + cb[0][5] + cb[1][6] + cb[0][7] + cb[1][8] + cb[0][9] + cb[1][10] + cb[0][11] + cb[1][12] + cb[0][13] + cb[1][14] + cb[0][15];
  1690.         else if (x == 15 && type == 2) i = cb[0][0] + cb[1][1] + cb[0][2] + cb[1][3] + cb[0][4] + cb[1][5] + cb[0][6] + cb[1][7] + cb[0][8] + cb[1][9] + cb[0][10] + cb[1][11] + cb[0][12] + cb[1][13] + cb[0][14];
  1691.         else return(FALSE);
  1692.  
  1693.         nbr = ap_psprintf(p, "%d", i);
  1694.         if (nbr[1] == '0') return(TRUE);
  1695.  
  1696.         return(FALSE);
  1697. }
  1698.  
  1699. /*--------------------------------------------------------------------------*/
  1700. /* ISEMAIL (verifie si la chaine est une adresse E-Mail                     */
  1701. /*--------------------------------------------------------------------------*/
  1702. static int isemail(const char *chaine)
  1703. {
  1704.         register int x;
  1705.  
  1706.         if (chaine == NULL) return(FALSE);
  1707.         x = strlen(chaine) - 1;
  1708.         if (x < 5) return(FALSE);       /* 6-1 est la plus petite adresse possible */
  1709.         if (strchr(chaine, '@') == NULL) return(FALSE)/* Il faut obligatoirement un '@' */
  1710.         if (chaine[x] == '@' || chaine[x] < 65 || chaine[0] < 48 || (chaine[0] > 57 && chaine[0] < 65)) return(FALSE)/* Il ne peut pas y avoir un de ces caractere a la fin et au debut */
  1711.         if (strchr(strchr(chaine, '@'), '.') == NULL) return(FALSE);    /* Il faut qu'il y est au moins un '.' derriere le '@' */
  1712.  
  1713.         return(TRUE);
  1714. }
  1715.  
  1716. /*--------------------------------------------------------------------------*/
  1717. /* Fonction ifvide                                                          */
  1718. /* Renvoi TRUE si la chaine est vide et FALSE sinon                         */
  1719. /*--------------------------------------------------------------------------*/
  1720. static int ifvide(const char *chaine)
  1721. {
  1722.         register x = -1;
  1723.         if (chaine == NULL) return(TRUE);
  1724.  
  1725.         while(chaine[++x] != '\0')
  1726.         {
  1727.                 if (chaine[x] > 32)     return(FALSE);       /* A trouve des caractere valides */
  1728.         }
  1729.         return(TRUE);
  1730. }
  1731.  
  1732. /*--------------------------------------------------------------------------*/
  1733. /* Renvoi le numero du jour de l'annee                                      */
  1734. /*--------------------------------------------------------------------------*/
  1735. static int jour_annee(int jour, int mois, int annee)
  1736. {
  1737.         int v, w;
  1738.  
  1739.         v = annee_bissex(annee);
  1740.         for (w = 1; w < mois; w++) jour += jour_dans_mois[v][w];
  1741.  
  1742.         return(jour);   /* Retourne le numero du jour de l'annee */
  1743. }
  1744.  
  1745. /*--------------------------------------------------------------------------*/
  1746. /* Renvoi le numero du jour de la semaine (dimanche = 1, lundi = 2, etc...  */
  1747. /*--------------------------------------------------------------------------*/
  1748. static int jour_semaine(int jour, int mois, int annee)
  1749. {
  1750.         long temp;
  1751.         int resultat;
  1752.  
  1753.         temp = (long)(annee - 1) * 365 + nombre_annee_bissex(annee - 1) + jour_annee(jour, mois, annee);
  1754.  
  1755.         if (temp < FIRST_MISSING_DAY) resultat = (temp -1 + SAMEDI) % 7;
  1756.         else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) resultat = ((temp - 1 + SAMEDI) - NUMBER_MISSING_DAYS) % 7;
  1757.         else resultat = JEUDI;
  1758.  
  1759.         return (resultat);
  1760. }
  1761.  
  1762. /*--------------------------------------------------------------------------*/
  1763. /* Renvoi FALSE (0) si la chaine ne peut pas etre une valeur numerique      */
  1764. /* Renvoi TRUE (1) si la chaine est conforme au type numerique (double)     */
  1765. /*--------------------------------------------------------------------------*/
  1766. static int isnum(const char *chaine)
  1767. {
  1768.         int x = -1, deb = FALSE, signe = FALSE, fin = FALSE, virg = FALSE, expo = FALSE, expsi = FALSE, chif = FALSE;
  1769.  
  1770.         while (chaine[++x] != '\0')
  1771.         {
  1772.                 if (deb)
  1773.                 {
  1774.                         if (!fin)
  1775.                         {
  1776.                                 if (chaine[x] < 33 || chaine[x] == 127) fin = TRUE;
  1777.                                 else if (chaine[x] == ',' || chaine[x] == '.')
  1778.                                 {
  1779.                                         if (!virg && !expo && isdigit(chaine[x-1])) virg = TRUE;
  1780.                                         else return(FALSE);
  1781.                                 }
  1782.                                 else if (chaine[x] == '+' || chaine[x] == '-')
  1783.                                 {
  1784.                                         if (!expo) return(FALSE);
  1785.                                         else if (!expsi && (chaine[x-1] == 'e' || chaine[x-1] == 'E')) expsi = TRUE;
  1786.                                         else return(FALSE);
  1787.                                 }
  1788.                                 else if (chaine[x] == 'e' || chaine[x] == 'E')
  1789.                                 {
  1790.                                         if (!expo && isdigit(chaine[x-1])) expo = TRUE;
  1791.                                         else return(FALSE);
  1792.                                 }
  1793.                                 else if (!isdigit((int)chaine[x])) return(FALSE);
  1794.                                 else chif = TRUE;
  1795.                         }
  1796.                         else if (chaine[x] > 32 && chaine[x] != 127) return(FALSE);
  1797.                 }
  1798.                 else if (chaine[x] == '+' || chaine[x] == '-') deb = signe = TRUE;
  1799.                 else if (chaine[x] > 32 && chaine[x] != 127)
  1800.                 {
  1801.                         if (!isdigit((int)chaine[x])) return(FALSE);
  1802.                         deb = chif = TRUE;
  1803.                 }
  1804.         }
  1805.         if (!chif) return(FALSE);
  1806.  
  1807.         return(TRUE);
  1808. }
  1809.  
  1810. /*--------------------------------------------------------------------------*/
  1811. /* Val = valeur numerique a convertir (32 bits maximum en unsigned)         */
  1812. /* Digit = nbr de digit pour le retour (entre 0 et 8 maximum)               */
  1813. /* Renvoi dans Chaine la valeur en Hexa qui ne depassera pas                */
  1814. /* le nombre de digit prevu                                                 */
  1815. /* Si result != NULL, alors ce sert de cette variable pour le calcul        */
  1816. /*--------------------------------------------------------------------------*/
  1817. static char *int_to_hex(pool *p, long unsigned int val, int digit, char *result)
  1818. {
  1819.         const unsigned char hexa[] = "0123456789ABCDEF";
  1820.         int i=0,j=0;
  1821.         long unsigned int quot, quot1, reste;
  1822.         char *temp;
  1823.  
  1824.         if (result == NULL) temp = ap_palloc(p, 9 * sizeof(char));      /* Alloue un emplacement memoire pour le resultat */
  1825.         else temp = result;
  1826.  
  1827.         quot1 = val;
  1828.         for (i = 7; i>=0; i--)
  1829.         {
  1830.                 quot = quot1 / 16;
  1831.                 reste = quot1 - (quot*16);
  1832.                 temp[i] = hexa[reste];
  1833.                 quot1 = quot;
  1834.                 if (j == 0 && quot <= 0) j = i;
  1835.         }
  1836.         temp[8] = '\0';
  1837.  
  1838.         if (digit > 0 && digit < 9) return(&temp[8-digit]);
  1839.  
  1840.         return(&temp[j]);
  1841. }
  1842.  
  1843. /*--------------------------------------------------------------------------*/
  1844. /* ListFields                                                               */
  1845. /*--------------------------------------------------------------------------*/
  1846. static int md_mysql_listfields(adml_mysql *base_mysql, const char *ftable, const char *wild)
  1847. {
  1848.         if (!base_mysql->fconnect) return(FALSE);
  1849.         base_mysql->fquery = base_mysql->ferror = FALSE;
  1850.  
  1851.         if ((base_mysql->res = mysql_list_fields(&base_mysql->mysql, ftable, wild)))
  1852.         {
  1853.                 base_mysql->row = mysql_fetch_row(base_mysql->res);
  1854.                 base_mysql->numligne = base_mysql->numcolonne = 0;
  1855.                 return(base_mysql->fquery = TRUE);
  1856.         }
  1857.  
  1858.         return(FALSE);
  1859. }
  1860.  
  1861. /*--------------------------------------------------------------------------*/
  1862. /* ListTables                                                               */
  1863. /*--------------------------------------------------------------------------*/
  1864. static int md_mysql_listtables(adml_mysql *base_mysql, const char *wild)
  1865. {
  1866.         if (!base_mysql->fconnect) return(FALSE);
  1867.         base_mysql->fquery = base_mysql->ferror = FALSE;
  1868.  
  1869.         if ((base_mysql->res = mysql_list_tables(&base_mysql->mysql, wild)))
  1870.         {
  1871.                 base_mysql->row = mysql_fetch_row(base_mysql->res);
  1872.                 base_mysql->numligne = base_mysql->numcolonne = 0;
  1873.                 return(base_mysql->fquery = TRUE);
  1874.         }
  1875.  
  1876.         return(FALSE);
  1877. }
  1878.  
  1879. /*--------------------------------------------------------------------------*/
  1880. /* ListDbs                                                                  */
  1881. /*--------------------------------------------------------------------------*/
  1882. static int md_mysql_listdbs(adml_mysql *base_mysql, const char *wild)
  1883. {
  1884.         if (!base_mysql->fconnect) return(FALSE);
  1885.         base_mysql->fquery = base_mysql->ferror = FALSE;
  1886.  
  1887.         if ((base_mysql->res = mysql_list_dbs(&base_mysql->mysql, wild)))
  1888.         {
  1889.                 base_mysql->row = mysql_fetch_row(base_mysql->res);
  1890.                 base_mysql->numligne = base_mysql->numcolonne = 0;
  1891.                 return(base_mysql->fquery = TRUE);
  1892.         }
  1893.  
  1894.         return(FALSE);
  1895. }
  1896.  
  1897. /*--------------------------------------------------------------------------*/
  1898. /* FreeResult                                                               */
  1899. /*--------------------------------------------------------------------------*/
  1900. static void md_mysql_freeresult(adml_mysql *base_mysql)
  1901. {
  1902.         if (base_mysql->fconnect) return;
  1903.  
  1904.         base_mysql->fquery = base_mysql->ferror = FALSE;
  1905.  
  1906.         mysql_free_result(base_mysql->res);
  1907. }
  1908.  
  1909. /*--------------------------------------------------------------------------*/
  1910. /* Recharge la table des utilisateurs (Grants)                              */
  1911. /*--------------------------------------------------------------------------*/
  1912. static int md_mysql_reload(adml_mysql *base_mysql)
  1913. {
  1914.         if (base_mysql->fconnect)
  1915.         {
  1916.                 if (mysql_reload(&base_mysql->mysql) == 0) return(TRUE);
  1917.         }
  1918.  
  1919.         base_mysql->ferror = TRUE;
  1920.         return(FALSE);
  1921. }
  1922.  
  1923. /*--------------------------------------------------------------------------*/
  1924. /* AddDataSeek                                                              */
  1925. /*--------------------------------------------------------------------------*/
  1926. static int md_mysql_add_dataseek(adml_mysql *base_mysql, int num)
  1927. {
  1928.         int x;
  1929.  
  1930.         x = base_mysql->numligne;       /* Sauvegarde la position actuelle */
  1931.         base_mysql->numligne += num;
  1932.         if ((base_mysql->numligne >= 0) && (base_mysql->numligne < mysql_num_rows(base_mysql->res)))
  1933.         {
  1934. /*
  1935.                 if ((base_mysql->row = mysql_fetch_row(base_mysql->res))) return(TRUE);
  1936. */
  1937.                 mysql_data_seek(base_mysql->res, base_mysql->numligne);
  1938.                 base_mysql->row = mysql_fetch_row(base_mysql->res);
  1939.                 return(TRUE);
  1940.         }
  1941.  
  1942.         base_mysql->numligne = x;
  1943.         return(FALSE);
  1944. }
  1945.  
  1946. /*--------------------------------------------------------------------------*/
  1947. /* AddFieldSeek                                                             */
  1948. /*--------------------------------------------------------------------------*/
  1949. static int md_mysql_add_fieldseek(adml_mysql *base_mysql, int num)
  1950. {
  1951.         int x;
  1952.  
  1953.         x = base_mysql->numcolonne;     /* Sauvegarde la position actuelle */
  1954.         base_mysql->numcolonne += num;
  1955.         if ((base_mysql->numcolonne >= 0) && (base_mysql->numcolonne < mysql_num_fields(base_mysql->res)))
  1956.         {
  1957. /*
  1958.                 if ((base_mysql->row = mysql_fetch_row(base_mysql->res))) return(TRUE);
  1959. */
  1960.                 mysql_field_seek(base_mysql->res, base_mysql->numcolonne);
  1961.                 return(TRUE);
  1962.         }
  1963.  
  1964.         base_mysql->numcolonne = x;
  1965.         return(FALSE);
  1966. }
  1967.  
  1968. /*--------------------------------------------------------------------------*/
  1969. /* Recupere la liste des processus lance sur le serveur                     */
  1970. /*--------------------------------------------------------------------------*/
  1971. static int md_mysql_processes(adml_mysql *base_mysql)
  1972. {
  1973.         if (!base_mysql->fconnect) return(FALSE);
  1974.  
  1975.         if ((base_mysql->res = mysql_list_processes(&base_mysql->mysql)))
  1976.         {
  1977.                 base_mysql->row = mysql_fetch_row(base_mysql->res);
  1978.                 base_mysql->numligne = base_mysql->numcolonne = 0;
  1979.                 base_mysql->ferror = FALSE;
  1980.                 return(base_mysql->fquery = TRUE);
  1981.         }
  1982.  
  1983.         base_mysql->ferror = TRUE;
  1984.         return(base_mysql->fquery = FALSE);
  1985. }
  1986.  
  1987. /*--------------------------------------------------------------------------*/
  1988. /* DataSeek                                                                 */
  1989. /*--------------------------------------------------------------------------*/
  1990. static int md_mysql_dataseek(adml_mysql *base_mysql, uint offset)
  1991. {
  1992.         if (!base_mysql->fquery) return(FALSE);
  1993.  
  1994.         if (offset >= 0 && offset < mysql_num_rows(base_mysql->res))
  1995.         {
  1996.                 mysql_data_seek(base_mysql->res, offset);
  1997.                 base_mysql->row = mysql_fetch_row(base_mysql->res);
  1998.                 base_mysql->numligne = offset;
  1999.                 base_mysql->numcolonne = 0;
  2000.                 return(TRUE);
  2001.         }
  2002.         else base_mysql->numligne = mysql_num_rows(base_mysql->res);
  2003.  
  2004.         return(FALSE);
  2005. }
  2006.  
  2007. /*--------------------------------------------------------------------------*/
  2008. /* FieldSeek                                                                */
  2009. /*--------------------------------------------------------------------------*/
  2010. static int md_mysql_fieldseek(adml_mysql *base_mysql, int numfield)
  2011. {
  2012.         if (!base_mysql->fquery) return(FALSE);
  2013.  
  2014.         if (numfield >= 0 && numfield < mysql_num_fields(base_mysql->res))
  2015.         {
  2016.                 mysql_field_seek(base_mysql->res, numfield);
  2017.                 base_mysql->field = mysql_fetch_field(base_mysql->res);
  2018.                 base_mysql->numcolonne = numfield;
  2019.                 return(TRUE);
  2020.         }
  2021.         else base_mysql->numcolonne = mysql_num_fields(base_mysql->res);
  2022.  
  2023.         return(FALSE);
  2024. }
  2025.  
  2026. /*--------------------------------------------------------------------------*/
  2027. /* envoi le nombre de Rows de la requete                                    */
  2028. /*--------------------------------------------------------------------------*/
  2029. static int md_mysql_nbrfields(adml_mysql *base_mysql)
  2030. {
  2031.         if (!base_mysql->fquery) return(0);
  2032.         return(mysql_num_fields(base_mysql->res));
  2033. }
  2034.  
  2035. /*--------------------------------------------------------------------------*/
  2036. /* envoi le nombre de Rows de la requete                                    */
  2037. /*--------------------------------------------------------------------------*/
  2038. static int md_mysql_nbrrows(adml_mysql *base_mysql)
  2039. {
  2040.         if (!base_mysql->fquery) return(0);
  2041.         return(mysql_num_rows(base_mysql->res));
  2042. }
  2043.  
  2044. /*--------------------------------------------------------------------------*/
  2045. /* Recuperation du message d'erreur s'il y en a un                          */
  2046. /*--------------------------------------------------------------------------*/
  2047. static char *md_mysql_error(adml_mysql *base_mysql)
  2048. {
  2049.         if (base_mysql->ferror)
  2050.         {
  2051.                 if (mysql_error(&base_mysql->mysql) == NULL) return("");        /* Il ne faut pas renvoyer un NULL */
  2052.                 else return(mysql_error(&base_mysql->mysql));
  2053.         }
  2054.         else return("");        /* Renvoi une chaine vide s'il n'y a pas d'erreur */
  2055. }
  2056.  
  2057. /*--------------------------------------------------------------------------*/
  2058. /* Deconnection a une base de donnees Mysql                                 */
  2059. /*--------------------------------------------------------------------------*/
  2060. static void md_mysql_close(adml_mysql *base_mysql)
  2061. {
  2062.         if (base_mysql->fconnect) mysql_close(&base_mysql->mysql);
  2063.         base_mysql->fconnect = base_mysql->fbase = base_mysql->fquery = base_mysql->ferror = FALSE;
  2064. }
  2065.  
  2066. /*--------------------------------------------------------------------------*/
  2067. /* Connection a une base de donnees Mysql                                   */
  2068. /*--------------------------------------------------------------------------*/
  2069. static int md_mysql_connect(adml_mysql *base_mysql, const char *host, const char *login, const char *passwd)
  2070. {
  2071.         md_mysql_close(base_mysql);     /* Fermeture au cas ou */
  2072.  
  2073.         if (!(mysql_connect(&base_mysql->mysql, host, login, passwd))) base_mysql->ferror = TRUE;
  2074.         else base_mysql->fconnect = TRUE;
  2075.  
  2076.         return(base_mysql->fconnect);
  2077. }
  2078.  
  2079. /*--------------------------------------------------------------------------*/
  2080. /* Selection d'une base de donnees Mysql                                    */
  2081. /*--------------------------------------------------------------------------*/
  2082. static int md_mysql_select(adml_mysql *base_mysql, const char *base)
  2083. {
  2084.         const char *labase;
  2085.  
  2086.         base_mysql->fquery = base_mysql->ferror = FALSE;
  2087.         if (!base_mysql->fconnect) return(FALSE);
  2088.  
  2089.         if (base == NULL) labase = "";
  2090.         else labase = base;
  2091.  
  2092.         if (mysql_select_db(&base_mysql->mysql, labase))
  2093.         {
  2094.                 base_mysql->ferror = TRUE;
  2095.                 return(base_mysql->fbase = FALSE);
  2096.         }
  2097.  
  2098.         return(base_mysql->fbase = TRUE);
  2099. }
  2100.  
  2101. /*--------------------------------------------------------------------------*/
  2102. /* Lance une requete SQL                                                    */
  2103. /*--------------------------------------------------------------------------*/
  2104. static int md_mysql_query(adml_mysql *base_mysql, const char *req)
  2105. {
  2106.         const char *lareq;
  2107.  
  2108.         base_mysql->fquery = FALSE;
  2109.  
  2110.         if (!base_mysql->fconnect) return(base_mysql->ferror = FALSE);
  2111.         else base_mysql->ferror = TRUE;
  2112.  
  2113.         if (req == NULL) lareq = "";
  2114.         else lareq = req;
  2115.  
  2116.         if (!mysql_query(&base_mysql->mysql, lareq))
  2117.         {
  2118.                 if (strstr(lareq, "INSERT") || strstr(lareq, "UPDATE") || strstr(lareq, "DELETE"))
  2119.                 {
  2120.                         base_mysql->ferror = FALSE;
  2121.                         return(TRUE);   // Ne positionne pas le fquery afin de ne pas pouvoir visualiser le nombre de Rows, etc... */
  2122.                 }
  2123.                 base_mysql->res = mysql_store_result(&base_mysql->mysql);
  2124.  
  2125.                 if (base_mysql->res)
  2126.                 {
  2127.                         base_mysql->row = mysql_fetch_row(base_mysql->res);
  2128.                         base_mysql->numligne = 0;       // Se positionne sur la premiere ligne
  2129.                         base_mysql->numcolonne = 0;     // et sur la premiere colonne
  2130.                         base_mysql->ferror = FALSE;
  2131.                         return(base_mysql->fquery = TRUE);
  2132.                 }
  2133.  
  2134.         }
  2135.  
  2136.         return(FALSE);
  2137. }
  2138.  
  2139. /*--------------------------------------------------------------------------*/
  2140. /* Execution des fonctions                                                  */
  2141. /*--------------------------------------------------------------------------*/
  2142. static char *exec_fonction(adml_cfg *conf, const char *chaine1, const char *chaine2)
  2143. {
  2144. #define N_TAG_PARAM 25
  2145.         char *ch1, *ch2, *param[N_TAG_PARAM], *ptr, *temp;
  2146.         unsigned char car;
  2147.         int x=-1, y, z, w, v, i, pos=0, nparam=0, flag;
  2148.         array_header *arr;
  2149.         table_entry *elts;
  2150.         struct tm *temps;
  2151.         div_t divis;
  2152.         time_t timestamp;
  2153.         unsigned char tr[256];
  2154.         struct in_addr addr;
  2155.  
  2156.         ch1 = (chaine1 != NULL) ? interp(conf ,chaine1) : "";   /* Interpretation */
  2157.  
  2158.         param[0] = "";
  2159.         while(ch1[++x] != '\0' && nparam < 20)
  2160.         {
  2161.                 if (nparam > 0)
  2162.                 {
  2163.                         if (ch1[x] == ',' || ch1[x] == ')')
  2164.                         {
  2165.                                 if (x - pos > 0) param[nparam] = ap_pstrndup(conf->pool_tag,&ch1[pos],x-pos);
  2166.                                 else param[nparam] = "";
  2167.                                 if (ch1[x] == ')') break;
  2168.                                 pos = x+1;
  2169.                                 nparam++;
  2170.                         }
  2171.                 }
  2172.                 else if (ch1[x] == '(')
  2173.                 {
  2174.                         param[nparam++] = ap_pstrndup(conf->pool_tag,ch1,x);    /* Recupere le nom de la fonction */
  2175.                         pos = x+1;
  2176.                 }
  2177.         }
  2178.         if (nparam < 1) param[0] = ch1; /* Recupere le nom de la fonction (dans le cas ou il n'y a pas de parametre) */
  2179.  
  2180.         if (chaine2 == NULL) ch2 = ""/* Chaine vide */
  2181.         else
  2182.         {
  2183.                 if (strcasecmp(param[0], "nointerp")) ch2 = interp(conf ,chaine2);      /* Interprete si ce n'est pas la fonction NOINTERP */
  2184.                 else ch2 = ap_pstrdup(conf->pool_tag, chaine2)/* N'interprete pas */
  2185.         }
  2186.  
  2187.         ch1 = "";
  2188.         pos = 0; v = 0; w = 0; x = 0; y = 0; z = 0;
  2189.         flag = FALSE;
  2190.  
  2191.         /*---------------------------------------------------------------------*/
  2192.         /* NOINTERP                                                            */
  2193.         /*---------------------------------------------------------------------*/
  2194.         if (!strcasecmp(param[0],"nointerp"))
  2195.         {
  2196.                 ch1 = ch2;      /* Pas d'interpretation */
  2197.         }
  2198.         /*---------------------------------------------------------------------*/
  2199.         /* CONV...                                                             */
  2200.         /*---------------------------------------------------------------------*/
  2201. #define TAILLE_SUP_CONV 128
  2202. #define TAILLE_LINK_MAX 100
  2203.         else if (!strncasecmp(param[0],"conv",4) || !strncasecmp(param[0], "link", 4) || !strncasecmp(param[0], "upper", 5) || !strncasecmp(param[0], "strupper", 8) || !strncasecmp(param[0], "strlower", 8)
  2204. || !strncasecmp(param[0], "lower", 5) || !strncasecmp(param[0], "encod", 5) || !strcasecmp(param[0], "html") || !strcasecmp(param[0], "br")
  2205. || !strcasecmp(param[0], "notag") || !strcasecmp(param[0], "eschtml") || !strcasecmp(param[0], "nohtml") || !strncasecmp(param[0], "mysqlesc", 8)
  2206. || !strcasecmp(param[0], "escmysql") || !strcasecmp(param[0], "nospc") || !strncasecmp(param[0], "testli", 6))
  2207.         {
  2208.                 ptr = NULL;
  2209.  
  2210.                 if (!strncasecmp(param[0], "link", 4) || !strncasecmp(param[0], "testli", 6))
  2211.                 {
  2212.                         if (nparam > 0) ptr = param[1];
  2213.                         if (!strncasecmp(param[0], "testli", 6)) v = 8192;      /* TESTLI... */
  2214.                         else v = 1;     /* LINK */
  2215.                 }
  2216.                 else
  2217.                 {
  2218.                         v = 0;
  2219.                         for (x = 0; x <=nparam; x++)
  2220.                         {
  2221.                                 if (!(v&1) && (!strncasecmp(param[x], "link", 4))) v += 1;
  2222.                                 else if (!(v&2) && (!strncasecmp(param[x], "upper", 5) || !strncasecmp(param[x], "strupper", 8))) v += 2;
  2223.                                 else if (!(v&4) && (!strncasecmp(param[x], "lower", 5) || !strncasecmp(param[x], "strlower", 8))) v += 4;
  2224.                                 else if (!(v&8) && !strncasecmp(param[x], "encod", 5)) v += 8;
  2225.                                 else if (!(v&16) && !strcasecmp(param[x], "html")) v += 16;
  2226.                                 else if (!(v&32) && !strcasecmp(param[x], "br")) v += 32;
  2227.                                 else if (!(v&64) && (!strcasecmp(param[x], "notag") || !strcasecmp(param[x], "nohtml") || !strcasecmp(param[x], "eschtml"))) v += 64;
  2228.                                 else if (!(v&128) && (!strncasecmp(param[x], "mysqlesc", 8) || !strcasecmp(param[x], "escmysql"))) v += 128;
  2229.                                 else if (!(v&256) && !strcasecmp(param[x], "trim")) v += 256;
  2230.                                 else if (!(v&512) && !strcasecmp(param[x], "nospc")) v += 512;
  2231.                                 else if (!(v&8192) && !strncasecmp(param[x], "testli", 6)) v += 8192;
  2232.                                 else if (!(v&1024) && !(v&2048) && !(v&4096))
  2233.                                 {
  2234.                                         if (!(v&1024) && !strcasecmp(param[x], "targtop"))
  2235.                                         {
  2236.                                                 ptr = "_top";
  2237.                                                 v += 1024;
  2238.                                         }
  2239.                                         else if (!(v&2048) && !strcasecmp(param[x], "targparent"))
  2240.                                         {
  2241.                                                 ptr = "_parent";
  2242.                                                 v += 2048;
  2243.                                         }
  2244.                                         else if (!(v&4096) && (!strcasecmp(param[x], "targblank") || !strcasecmp(param[x], "targnew")))
  2245.                                         {
  2246.                                                 ptr = "_blank";
  2247.                                                 v += 4096;
  2248.                                         }
  2249.                                 }
  2250.                         }       
  2251.                 }
  2252.  
  2253.                 if (v&2 && v&4) v -= 6/* Supprime MAJ et MIN s'il sont tous les deux actifs */
  2254.  
  2255.                 ch1 = ap_palloc(conf->pool_tag, sizeof(char) * (y = (x = strlen(ch2)) + TAILLE_SUP_CONV));      /* Calcul la taille de ch2 (x) et alloue une zone memoire de depart (y) */
  2256.  
  2257.         for (pos = 0, w = 0; pos < x; pos++)        /* Parcour la chaine ch2 */
  2258.                 {
  2259.                         /* ---------- NOSPC et le cotes gauche de TRIM ---------- */
  2260.                         if ((!(v&512) || ch2[pos] != ' ') && (!(v&256) || ch2[pos] != ' ' || flag))
  2261.                         {
  2262.                                 flag = TRUE;
  2263.                                 /* ---------- BR ---------- */
  2264.                                 if ((v&32) && !(v&8) && (ch2[pos] == '\n' || ch2[pos] == '\r'))
  2265.                                 {
  2266.                                         if (ch2[pos] == '\n')
  2267.                                         {
  2268.                                                 strcpy(&ch1[w], "<BR>");
  2269.                                                 w +=4;
  2270.                                         }
  2271.                                 }
  2272.                                 /* ---------- LINK... ---------- */
  2273.                                 else if (((v&1) || (v&8192)) && !(v&8) && (!strncasecmp(&ch2[pos], "http://", 7) || !strncasecmp(&ch2[pos], "mailto:", 7)))
  2274.                                 {
  2275.                                         z = pos + 6;    /* saute l'entete http:// ou mailto: */
  2276.                                         while((car = ch2[++z]) != '\0' && (unsigned char)car > 44 && car != ';' && (z < pos + TAILLE_LINK_MAX));
  2277.                                         if (z < (pos + TAILLE_LINK_MAX))        /* Verifie si le lien n'est pas trop long */
  2278.                                         {
  2279.                                                 if (!(v&8192) || strncasecmp(&ch2[pos], "mailto:", 7) || isemail(ap_pstrndup(conf->pool_tag, &ch2[pos+7], z - pos - 7)))        /* Verifie si l'email a une syntaxe correct si TESTLINK */
  2280.                                                 {
  2281.                                                         if (ptr != NULL) i = strlen(ptr);       /* Recupere la taille du target */
  2282.                                                         else i = 0;     /* Pas de target */
  2283.                                                         if (w + ((z - pos) * 2) + 40 + i > y)   /* Realloue un nouvel emplacement memoire plus grand */
  2284.                                                         {
  2285.                                                                 conf->temp = ap_palloc(conf->pool_tag, sizeof(char) * (y += TAILLE_SUP_CONV + ((z - pos) * 2) + 40));
  2286.                                                                 memcpy(conf->temp, ch1, w);     /* recopie la chaine */
  2287.                                                                 ch1 = conf->temp;
  2288.                                                         }
  2289.                                                         strcpy(&ch1[w], "<A ");
  2290.                                                         w += 3;
  2291.                                                         if (ptr != NULL)        /* Si il y a un target */
  2292.                                                         {
  2293.                                                                 strcpy(&ch1[w], "TARGET=\"");
  2294.                                                                 w += 8;
  2295.                                                                 strcpy(&ch1[w], ptr);   /* Place le nom du target */
  2296.                                                                 w += i;
  2297.                                                                 strcpy(&ch1[w], "\" ");
  2298.                                                                 w += 2;
  2299.                                                         }
  2300.                                                         i = z - pos;    /* Calcul la taille */
  2301.                                                         strcpy(&ch1[w], "HREF=\"");
  2302.                                                         w += 6;
  2303.                                                         strncpy(&ch1[w], ap_pstrndup(conf->pool_tag, &ch2[pos], i), i);
  2304.                                                         w += i;
  2305.                                                         strcpy(&ch1[w], "\">");
  2306.                                                         w += 2;
  2307.  
  2308.                                                         if (!strncasecmp(&ch2[pos], "mailto:", 7))
  2309.                                                         {
  2310.                                                                 i -= 7/* Retire le mailto: */
  2311.                                                                 strncpy(&ch1[w], &ch2[pos + 7], i);
  2312.                                                         }
  2313.                                                         else strncpy(&ch1[w], &ch2[pos], i);
  2314.                                                         w += i;
  2315.  
  2316.                                                         strcpy(&ch1[w], "</A>");
  2317.                                                         w += 4;
  2318.  
  2319.                                                         pos = z - 1;    /* Nouvelle position */
  2320.                                                 }
  2321.                                                 else goto CONV_GOTO; /* Finalement, ce n'est pas un lien */
  2322.                                         }
  2323.                                         else goto CONV_GOTO; /* Finalement, ce n'est pas un lien */
  2324.                                 }
  2325.                                 else
  2326.                                 {
  2327. CONV_GOTO:
  2328.                                         /* ---------- UPPER... ---------- */
  2329.                                         if (v&2 && islower(ch2[pos]))
  2330.                                         {
  2331.                                                 ch2[pos] = toupper(ch2[pos]);
  2332.                                         }
  2333.                                         /* ---------- LOWER... ---------- */
  2334.                                         else if (v&4 && isupper(ch2[pos]))
  2335.                                         {
  2336.                                                 ch2[pos] = tolower(ch2[pos]);
  2337.                                         }
  2338.  
  2339.                                         if ((v&8) || (v&128))
  2340.                                         {
  2341.                                                 /* ---------- ENCODED... ---------- */
  2342.                                                 if (v&8 && (ch2[pos] == '\'' || ch2[pos] == '\0' || ch2[pos] == ' ' || ch2[pos] == '|' || ch2[pos] == '=' || ch2[pos] == '+' || ch2[pos] == '&' || ch2[pos] == '\n' || ch2[pos] == '\r' || ch2[pos] == '%' || ch2[pos] == '\\' || ch2[pos] == '/' || ch2[pos] == '?'))
  2343.                                                 {
  2344.                                                         if (ch2[pos] == ' ') ch1[w++] = '+';
  2345.                                                         else if (ch2[pos] == '\'') ch1[w++] = ch2[pos]/* Recopie le caractere sans traitement */
  2346.                                                         else
  2347.                                                         {
  2348.                                                                 ch1[w++] = '%';
  2349.                                                                 divis = div((unsigned int)ch2[pos], 16);
  2350.                                                                 ch1[w++] = hexa[divis.quot];
  2351.                                                                 ch1[w++] = hexa[divis.rem];
  2352.                                                         }
  2353.                                                 }
  2354.                                                 /* ---------- MYSQLESC ou ESCMYSQL ---------- */
  2355.                                                 else if (ch2[pos] == '\0' || ch2[pos] == '\n' || ch2[pos] == '\r' || ch2[pos] == '\\' || ch2[pos] == '\'')
  2356.                                                 {
  2357.                                                         ch1[w++] = '\\';
  2358.                                                         if (ch2[pos] == '\0') ch1[w++] = '0';
  2359.                                                         else if (ch2[pos] == '\n') ch1[w++] = 'n';
  2360.                                                         else if (ch2[pos] == '\r') ch1[w++] = 'r';
  2361.                                                         else if (ch2[pos] == '\\') ch1[w++] = '\\';
  2362.                                                         else if (ch2[pos] == '\'') ch1[w++] = '\'';
  2363.                                                 }
  2364.                                                 /* ---------- Recopie le caractere sans traitement ---------- */
  2365.                                                 else ch1[w++] = ch2[pos];
  2366.                                         }
  2367.                                         else
  2368.                                         {
  2369.                                                 /* ---------- NOTAG ou ESCHTML ---------- */
  2370.                                                 if (v&64 && (ch2[pos] == '<' || ch2[pos] == '>' || ch2[pos] == '&' || ch2[pos] == '\"'))
  2371.                                                 {
  2372.                                                         if (ch2[pos] == '<')
  2373.                                                         {
  2374.                                                                 strcpy(&ch1[w], "&lt;");
  2375.                                                                 w += 4;
  2376.                                                         }
  2377.                                                         else if (ch2[pos] == '>')
  2378.                                                         {
  2379.                                                                 strcpy(&ch1[w], "&gt;");
  2380.                                                                 w += 4;
  2381.                                                         }
  2382.                                                         else if (ch2[pos] == '&')
  2383.                                                         {
  2384.                                                                 strcpy(&ch1[w], "&amp;");
  2385.                                                                 w += 5;
  2386.                                                         }
  2387.                                                         else if (ch2[pos] == '\"')
  2388.                                                         {
  2389.                                                                 strcpy(&ch1[w], "&quot;");
  2390.                                                                 w += 6;
  2391.                                                         }
  2392.                                                 }
  2393.                                                 /* ---------- HTML... ---------- */
  2394.                                                 else if (v&16)
  2395.                                                 {
  2396.                                                         if ((unsigned char)ch2[pos] >= 160 && (unsigned char)ch2[pos] < 256)
  2397.                                                         {
  2398.                                                                 z = (unsigned char)ch2[pos];
  2399.                                                                 ch1[w++] = '&';
  2400.                                                                 strcpy(&ch1[w], code_html[z - 160]);
  2401.                                                                 w += strlen(code_html[z - 160]);
  2402.                                                                 ch1[w++] = ';';
  2403.                                                         }
  2404.                                                         else if (ch2[pos] == '&')
  2405.                                                         {
  2406.                                                                 strcpy(&ch1[w], "&amp;");
  2407.                                                                 w += 5;
  2408.                                                         }
  2409.                                                         else ch1[w++] = ch2[pos];       /* Recopie le caractere sans traitement */
  2410.                                                 }
  2411.                                                 /* ---------- Recopie le caractere sans traitement ---------- */
  2412.                                                 else ch1[w++] = ch2[pos];
  2413.                                         }
  2414.                                 }
  2415.  
  2416.                         }
  2417.  
  2418.                         if (w + 15 > y) /* Realloue un nouvel emplacement memoire plus grand */
  2419.                         {
  2420.                                 conf->temp = ap_palloc(conf->pool_tag, sizeof(char) * (y += TAILLE_SUP_CONV));
  2421.                                 memcpy(conf->temp, ch1, w);     /* recopie la chaine */
  2422.                                 ch1 = conf->temp;
  2423.                         }
  2424.                 }
  2425.  
  2426.                 /* ---------- TRIM partie droite ---------- */
  2427.                 if (v&256)
  2428.                 {
  2429.                         while(ch1[--w] == ' ')/* Retire les espaces en fin de chaine */
  2430.                         w++;
  2431.                 }
  2432.                 ch1[w] = '\0'/* Place le fin de chaine */
  2433.         }
  2434.         /*---------------------------------------------------------------------*/
  2435.         /* TRIM...(car)                                                        */
  2436.         /*---------------------------------------------------------------------*/
  2437.         else if (!strcasecmp(param[0],"trim"))
  2438.         {
  2439.                 if (nparam > 0) car = param[1][0];
  2440.                 else car = ' '/* Par defaut */
  2441.                 ch1 = trim(ch2, car);
  2442.         }
  2443.         /*---------------------------------------------------------------------*/
  2444.         /* BOOL...                                                             */
  2445.         /*---------------------------------------------------------------------*/
  2446.         else if (!strncasecmp(param[0],"bool",4))
  2447.         {
  2448.                 if (!strcasecmp(ch2, "true")) ch1 = "1";        /* TRUE */
  2449.                 else ch1 = "0"/* FALSE */
  2450.         }
  2451.         /*---------------------------------------------------------------------*/
  2452.         /* TRUE                                                                */
  2453.         /*---------------------------------------------------------------------*/
  2454.         else if (!strcasecmp(param[0],"true")) ch1 = "1";
  2455.         /*---------------------------------------------------------------------*/
  2456.         /* FALSE                                                               */
  2457.         /*---------------------------------------------------------------------*/
  2458.         else if (!strcasecmp(param[0],"false")) ch1 = "0";
  2459.         /*---------------------------------------------------------------------*/
  2460.         /* UUENCOD...                                                          */
  2461.         /*---------------------------------------------------------------------*/
  2462.         else if (!strncasecmp(param[0],"uuencod", 7)) ch1 = ap_uuencode(conf->pool_tag, ch2);
  2463.         /*---------------------------------------------------------------------*/
  2464.         /* UUDECOD...                                                          */
  2465.         /*---------------------------------------------------------------------*/
  2466.         else if (!strncasecmp(param[0],"uudecod", 7)) ch1 = ap_uudecode(conf->pool_tag, ch2);
  2467.         /*---------------------------------------------------------------------*/
  2468.         /* WORD...(n,n,n) et QWORD...(n,n,n)                                   */
  2469.         /*---------------------------------------------------------------------*/
  2470.         else if (!strncasecmp(param[0], "word", 4) || !strncasecmp(param[0], "qword", 5))
  2471.         {
  2472.                 if (nparam > 0) y = atoi(param[1]);     /* Numero du mot a recuperer */
  2473.                 if (nparam > 1) w = atoi(param[2]);     /* Taille minimum du mot */
  2474.                 if (nparam > 2) v = atoi(param[3]);     /* Taille maximum du mot */
  2475.  
  2476.                 if (!strncasecmp(param[0], "q", 1)) flag = TRUE;        /* S'il faut prendre en compte les guillemets */
  2477.  
  2478.                 if ((temp = (char *)recupmots(conf->pool_tag, ch2, y, w, v, flag, 0, NULL)) != NULL) ch1 = temp;
  2479.         }
  2480.         /*---------------------------------------------------------------------*/
  2481.         /* ELT(x,x,...),n
  2482.         /*---------------------------------------------------------------------*/
  2483.         else if (!strcasecmp(param[0],"elt"))
  2484.         {
  2485.                 if (nparam > 0)
  2486.                 {
  2487.                         x = atoi(ch2) + 1;
  2488.                         if (x < 1 || x > nparam) x = 1/* Verifie que l'on ne soit pas hors-zone */
  2489.             ch1 = param[x]; // Sort l'element selectionne
  2490.                 }
  2491.                 else
  2492.                 {
  2493.                         /* WARNING: aucun parametre a la fonction */
  2494.                 }
  2495.         }
  2496.         /*---------------------------------------------------------------------*/
  2497.         /* NUM(precision,largeur,type) et CALC(precision,largeur,type)         */
  2498.         /*---------------------------------------------------------------------*/
  2499.         else if (!strcasecmp(param[0],"num") || !strcasecmp(param[0], "calc"))
  2500.         {
  2501.                 if (nparam > 2)
  2502.                 {
  2503.                         if (strcmp(param[3], "-") && strcmp(param[3], "+") && strcmp(param[3], "0")) param[3] = "0";
  2504.                 }
  2505.                 else param[3] = "0";
  2506.  
  2507.                 if (nparam > 1) x = atoi(param[2]);     /* Largeur */
  2508.                 else x = 0;
  2509.  
  2510.                 if (nparam > 0) z = atoi(param[1]);     /* Precision (nombre de decimal) */
  2511.                 else z = 6;
  2512.  
  2513.                 ch1 = ap_psprintf(conf->pool_tag, "%%%s%d.%dlf", param[3], x, z);
  2514.                 if (!strcasecmp(param[0], "num"))       /* Fonction NUM */
  2515.                 {
  2516.                         if ((ptr = strchr(ch2, ',')) != NULL) ptr[0] = '.';     /* Remplacer la virgule par un point pour que atof() convertisse correctement */
  2517.                         ch1 = ap_psprintf(conf->pool_tag, ch1, atof(ch2));
  2518.                         if (ptr != NULL) ptr[0] = ','/* Remettre la virgule */
  2519.                 }
  2520.                 else    /* Fonction CALC */
  2521.                 {
  2522.                         ch1 = ap_psprintf(conf->pool_tag, ch1, calc(conf, ch2));
  2523.                 }
  2524.         }
  2525.         /*---------------------------------------------------------------------*/
  2526.         /* RIGHT(n,n) et LEFT(n,n)                                             */
  2527.         /*---------------------------------------------------------------------*/
  2528.         else if (!strcasecmp(param[0],"right") || !strcasecmp(param[0],"left"))
  2529.         {
  2530.                 if (nparam > 0) /* Il faut au moins 1 parametre */
  2531.                 {
  2532.                         v = strlen(ch2);                                        /* Recupere la taille de la chaine a traiter */
  2533.                         w = (!strcmp(param[1],"*")) ? v : atoi(param[1]);       /* Recupere le premier parametre (le nombre de caracteres a prendre) */
  2534.                         if (w < 0) w = 0;                                   /* Interdit les valeurs negatives */
  2535.                         if (nparam > 1) x = atoi(param[2]);               /* Recupere le 2eme parametre (le debut a partir du bord) */
  2536.                         x = (x < 0) ? 0 : x;                    /* Interdit d'etre en negatif */
  2537.  
  2538.                         if (x < v)      /* Si le 2eme parametre ne depasse pas la taille de la chaine */
  2539.                         {
  2540.                                 if (w > v - x) w = v-x;    /* verifie que la longueur ne soit pas trop longue */
  2541.                                 if ((!strcasecmp(param[0], "right")) && x > 0) x = v -x -w;
  2542.  
  2543.                                 ch1 = ap_pstrndup(conf->pool_tag, &ch2[x], w)/* Recopie le nombre de caracteres demande */
  2544.                         }
  2545.                 }
  2546.                 else ch1 = ch2; /* Recopie la chaine dans son integralite */
  2547.         }
  2548.         /*---------------------------------------------------------------------*/
  2549.         /* HOSTTOIP                                                            */
  2550.         /*---------------------------------------------------------------------*/
  2551.         else if (!strcasecmp(param[0], "hosttoip"))
  2552.         {
  2553.                 if ((long)(addr.s_addr = get_ip(ch2)) > 0) ch1 = inet_ntoa(addr);
  2554.         }
  2555.         /*---------------------------------------------------------------------*/
  2556.         /* SERVICETOPORT                                                       */
  2557.         /*---------------------------------------------------------------------*/
  2558.         else if (!strcasecmp(param[0], "servicetoport"))
  2559.         {
  2560.                 if ((x = get_port(ch2)) > 0) ch1 = ap_psprintf(conf->pool_tag, "%d", ntohs(x));
  2561.         }
  2562.         /*---------------------------------------------------------------------*/
  2563.         /* SOCK...                                                             */
  2564.         /*---------------------------------------------------------------------*/
  2565.         else if (!strncasecmp(param[0], "sock", 4))
  2566.         {
  2567.                 x = (nparam > 0) ? atoi(param[1]) : 0/* numero de structure */
  2568.  
  2569.                 if (x >= 0 && x < N_SOCKET)
  2570.                 {
  2571.                         if (!strncasecmp(param[0], "sock", 4))
  2572.                         {
  2573.                                 if (!strcasecmp(ch2, "buffer")) ch1 = ap_pstrdup(conf->pool_tag, conf->sock[x].buffer);
  2574.                                 else if (!strncasecmp(ch2, "bufferlen", 9)) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->sock[x].taille_buffer);       /* Taille des donnees contenu dans le buffer de la socket */
  2575.                         }
  2576.                 }
  2577.         }
  2578.         /*---------------------------------------------------------------------*/
  2579.         /* UPLOAD... et ISUPLOAD... et IFUPLOAD...                             */
  2580.         /*---------------------------------------------------------------------*/
  2581.         else if (!strncasecmp(param[0], "isupload", 8) || !strncasecmp(param[0], "ifupload", 8) || !strncasecmp(param[0], "upload", 6))
  2582.         {
  2583.                 v = (nparam > 0) ? atoi(param[1]) : 0;
  2584.                 z = -1;
  2585.  
  2586.                 if (ch2[0] == '_')
  2587.                 {
  2588.                         if (!strcasecmp(ch2, "_nbr")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->nupload);   /* Nombre de champ upload */
  2589.                         else if (!strncasecmp(ch2, "_pos", 4)) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->upload_num);       /* Position courante */
  2590.                 }
  2591.                 else
  2592.                 {
  2593.                         if (ch2[0] != '#')      /* Recherche en nom */
  2594.                         {
  2595.                                 for(y=0, w=0; y < conf->nupload; y++)
  2596.                                 {
  2597.                                         if (!ap_strcmp_match(conf->upload[y].name, ch2))
  2598.                                         {
  2599.                                                 if (w++ >= v)   /* Pour le nbr de champ */
  2600.                                                 {
  2601.                                                         z = y;
  2602.                                                         break;
  2603.                                                 }
  2604.                                         }
  2605.                                 }
  2606.                         }
  2607.                         else if (!strcmp(ch2, "#"))     /* Position courante */
  2608.                         {
  2609.                                 if (conf->upload_num >= 0 && conf->upload_num < conf->nupload) z = conf->upload_num;    /* Trouver */
  2610.                         }
  2611.                         else if (isnum(&ch2[1]) && strlen(&ch2[1]) > 0) /* Recherche avec le numero du champ */
  2612.                         {
  2613.                                 i = atoi(&ch2[1]);
  2614.                                 if (i >= 0 && i < conf->nupload) z = i; /* Trouver */
  2615.                         }
  2616.  
  2617.                         if (z < 0)
  2618.                         {
  2619.                                 if (!strncasecmp(param[0], "i", 1)) ch1 = "0"/* Pour le ISUPLOAD */
  2620.                         }
  2621.                         else
  2622.                         {
  2623.                                                 if (!strncasecmp(param[0], "i", 1))     /* Pour le ISUPLOAD */
  2624.                                                 {
  2625.                                                         if (!strncasecmp(&param[0][8], "sav", 3))
  2626.                                                         {
  2627.                                                                 if (!conf->upload[z].save) ch1 = "0";   /* L'upload n'a pas encore ete sauvegarde */
  2628.                                                                 else ch1 = "1"/* Upload sauvegarder */
  2629.                                                         }
  2630.                                                         else ch1 = "1";
  2631.                                                 }
  2632.                                                 else if (!strncasecmp(&param[0][6], "nam", 3) || !strcasecmp(&param[0][6], "nom")) ch1 = conf->upload[z].name/* Renvoi le nom du champ upload */
  2633.                                                 else if (!strncasecmp(&param[0][6], "file", 4) || !strncasecmp(&param[0][6], "fic", 3)) ch1 = conf->upload[z].filename/* Renvoi le nom du fichier */
  2634.                                                 else if (!strncasecmp(&param[0][6], "rfile", 5) || !strncasecmp(&param[0][6], "rfic", 4)) ch1 = conf->upload[z].remote_filename;        /* Renvoi le chemin complet du fichier sur la machine remote */
  2635.                                                 else if (!strncasecmp(&param[0][6], "typ", 3)) ch1 = conf->upload[z].content_type;      /* Renvoi le type des donnees du champ upload */
  2636.                                                 else if (!strncasecmp(&param[0][6], "len", 3) || !strncasecmp(&param[0][6], "taille", 6)) ch1 = ap_psprintf(conf->pool_tag, "%lu", conf->upload[z].taille);     /* Renvoi la taille des donnees du champ upload  */
  2637.                                                 else if (!strncasecmp(&param[0][6], "val", 3)) ch1 = conf->upload[z].data;      /* Renvoi les donnees du champ upload */
  2638.                                                 else if (!strncasecmp(&param[0][6], "pos", 3)) ch1 = ap_psprintf(conf->pool_tag, "%d", z);      /* Renvoi la position du champ upload */
  2639.                                                 else if (!strncasecmp(&param[0][6], "ext", 3))
  2640.                                                 {
  2641.                                                         if ((temp = strrchr(conf->upload[z].filename, '.')) != NULL) ch1 = ap_pstrdup(conf->pool_tag, temp);    /* Retourne l'extension du fichier s'il y en a un */
  2642.                                                 }
  2643.                                                 else if (!strncasecmp(&param[0][6], "sav", 3))  /* renvoi le nom du fichier sauvegarde si l'upload a ete sauver */
  2644.                                                 {
  2645.                                                         if (conf->upload[z].save) ch1 = conf->upload[z].save;
  2646.                                                 }
  2647.                         }
  2648.                 }
  2649.         }
  2650.         /*---------------------------------------------------------------------*/
  2651.         /* HEADER... et ISHEADER...                                            */
  2652.         /*---------------------------------------------------------------------*/
  2653.         else if (!strncasecmp(param[0], "isheader", 8) || !strncasecmp(param[0], "ifheader", 8) || !strncasecmp(param[0], "header", 6))
  2654.         {
  2655.                 v = (nparam > 0) ? atoi(param[1]) : 1;
  2656.  
  2657.                 if (!strncasecmp(param[0], "headerauth", 10) || !strncasecmp(param[0], "isheaderauth", 12) || !strncasecmp(param[0], "ifheaderauth", 12))
  2658.                 {
  2659.                         if (conf->auth_user != NULL)
  2660.                         {
  2661.                                 if (!strncasecmp(param[0], "i", 1)) ch1 = "1"/* Oui, il y a un element d'entete Authorization: */
  2662.                                 else if (!strncasecmp(ch2, "user", 4) || !strcasecmp(ch2, "name")) ch1 = ap_pstrdup(conf->pool_tag, conf->auth_user);   /* Le USER */
  2663.                                 else if (!strncasecmp(ch2, "pass", 4)) ch1 = ap_pstrdup(conf->pool_tag, conf->auth_passwd);     /* Le PASSWORD */
  2664.                                 else if (!strcasecmp(ch2, "type")) ch1 = ap_pstrdup(conf->pool_tag, conf->auth_type);   /* Le TYPE d'authentification */
  2665.                         }
  2666.                         else if (tolower(param[0][0]) == 'i') ch1 = "0";        /* si le nom de la commande commence par un i (pour is ou if) */
  2667.                 }
  2668.                 else
  2669.                 {
  2670.                         if (tolower(param[0][0]) == 'i') i = 1/* Pour le ISHEADER ou IFHEADER */
  2671.                         else if (!strncasecmp(param[0], "headernam", 9)) i = 2/* nom du champ */
  2672.                         else if (!strncasecmp(param[0], "headerlen", 9)) i = 3/* taille du champ */
  2673.                         else if (!strncasecmp(param[0], "headerpos", 9)) i = 4/* position du champ dans la table */
  2674.                         else i = 0;
  2675.  
  2676.                         ch1 = cherche_table(conf, conf->r->headers_in, conf->headers_in_num, v, ch2, i, TRUE);
  2677.                 }
  2678.         }
  2679.         /*---------------------------------------------------------------------*/
  2680.         /* COOKIE... et ISCOOKIE...                                            */
  2681.         /*---------------------------------------------------------------------*/
  2682.         else if (!strcasecmp(param[0], "iscookie") || !strcasecmp(param[0], "ifcookie") || !strncasecmp(param[0], "cookie", 6))
  2683.         {
  2684.                 v = (nparam > 0) ? atoi(param[1]) : 1;
  2685.  
  2686.                 if (!strncasecmp(param[0], "i", 1)) i = 1;      /* Pour le ISCOOKIE ou IFCOOKIE */
  2687.                 else if (!strncasecmp(param[0], "cookienam", 9)) i = 2/* nom du champ */
  2688.                 else if (!strncasecmp(param[0], "cookielen", 9)) i = 3/* taille du champ */
  2689.                 else if (!strncasecmp(param[0], "cookiepos", 9)) i = 4/* position du champ dans la table */
  2690.                 else i = 0;
  2691.  
  2692.                 ch1 = cherche_table(conf, conf->cookies.tab, conf->cookies.pos, v, ch2, i, FALSE);
  2693.         }
  2694.         /*---------------------------------------------------------------------*/
  2695.         /* FORM... et ISFORM...                                                */
  2696.         /*---------------------------------------------------------------------*/
  2697.         else if (!strncasecmp(param[0], "isform", 6) || !strncasecmp(param[0], "ifform", 6) || !strncasecmp(param[0], "form", 4))
  2698.         {
  2699.                 x = (nparam > 0) ? atoi(param[1]) : conf->form_def;     /* numero de structure */
  2700.                 v = (nparam > 1) ? atoi(param[2]) : 1;
  2701.  
  2702.                 if (!strncasecmp(param[0], "i", 1)) i = 1;      /* Pour le ISFORM ou IFFORM */
  2703.                 else if (!strncasecmp(param[0], "formnam", 7)) i = 2;   /* nom du champ */
  2704.                 else if (!strncasecmp(param[0], "formlen", 7)) i = 3;   /* taille du champ */
  2705.                 else if (!strncasecmp(param[0], "formpos", 7)) i = 4;   /* position du champ dans la table */
  2706.                 else if (!strncasecmp(param[0], "formbool", 8)) i = 5/* Retourne un boolean */
  2707.                 else if (!strncasecmp(param[0], "formint", 7)) i = 6;   /* Retourne un entier */
  2708.                 else if (!strncasecmp(param[0], "formnum", 7)) i = 7;   /* Retourne un Float */
  2709.                 else i = 0;
  2710.  
  2711.                 if (x < N_FORM && x > -1)       /* Si le numero de structure est correct */
  2712.                 {
  2713.                         ch1 = cherche_table(conf, conf->form[x].tab, conf->form[x].pos, v, ch2, i, FALSE);
  2714.                 }
  2715.                 else if (i==1 || (i>4 && i<8)) ch1 = "0";       /* Pour le ISFORM, IFFORM, FORMBOOL, FORMNUM et FORMINT */
  2716.         }
  2717.         /*---------------------------------------------------------------------*/
  2718.         /* VAR... et ISVAR...                                                  */
  2719.         /*---------------------------------------------------------------------*/
  2720.         else if (!strncasecmp(param[0], "isvar", 5) || !strncasecmp(param[0], "ifvar", 5) || !strncasecmp(param[0], "var", 3))
  2721.         {
  2722.                 x = (nparam > 0) ? atoi(param[1]) : conf->var_def;      /* numero de structure */
  2723.                 v = (nparam > 1) ? atoi(param[2]) : 1;
  2724.  
  2725.                 if (!strncasecmp(param[0], "i", 1)) i = 1;      /* Pour le ISVAR ou IFVAR */
  2726.                 else if (!strncasecmp(param[0], "varnam", 6)) i = 2;    /* nom du champ */
  2727.                 else if (!strncasecmp(param[0], "varlen", 6)) i = 3;    /* taille du champ */
  2728.                 else if (!strncasecmp(param[0], "varpos", 6)) i = 4;    /* position du champ dans la table */
  2729.                 else if (!strncasecmp(param[0], "varbool", 7)) i = 5;   /* Retourne un boolean */
  2730.                 else if (!strncasecmp(param[0], "varint", 6)) i = 6;    /* Retourne un entier */
  2731.                 else if (!strncasecmp(param[0], "varnum", 6)) i = 7;    /* Retourne un Float */
  2732.                 else i = 0;
  2733.  
  2734.                 if (x < N_VAR && x > -1)        /* Si le numero de structure est correct */
  2735.                 {
  2736.                         ch1 = cherche_table(conf, conf->var[x].tab, conf->var[x].pos, v, ch2, i, FALSE);
  2737.                 }
  2738.                 else if (i==1 || (i>4 && i<8)) ch1 = "0";       /* Pour le ISVAR, IFVAR, VARBOOL, VARNUM et VARINT */
  2739.         }
  2740.         /*---------------------------------------------------------------------*/
  2741.         /* IS...                                                               */
  2742.         /*---------------------------------------------------------------------*/
  2743.         else if (!strncasecmp(param[0], "is", 2))
  2744.         {
  2745.                 ch1 = "0";      /* Par defaut */
  2746.                 /*---------------------------------------------------------------------*/
  2747.                 /* ISSHOW                                                              */
  2748.                 /*---------------------------------------------------------------------*/
  2749.                 if (!strcasecmp(param[0], "isshow"))
  2750.                 {
  2751.                         if (if_sortie) ch1 = "1";
  2752.                 }
  2753.                 /*---------------------------------------------------------------------*/
  2754.                 /* ISEMAIL                                                             */
  2755.                 /*---------------------------------------------------------------------*/
  2756.                 else if (!strcasecmp(param[0], "isemail"))
  2757.                 {
  2758.                         if (isemail(ch2)) ch1 = "1";
  2759.                 }
  2760.                 /*---------------------------------------------------------------------*/
  2761.                 /* ISEMPTY                                                             */
  2762.                 /*---------------------------------------------------------------------*/
  2763.                 else if (!strcasecmp(param[0], "isempty"))
  2764.                 {
  2765.                         if (ifvide(ch2)) ch1 = "1";
  2766.                 }
  2767.                 /*---------------------------------------------------------------------*/
  2768.                 /* ISNUM...                                                            */
  2769.                 /*---------------------------------------------------------------------*/
  2770.                 else if (!strncasecmp(param[0], "isnum", 5))
  2771.                 {
  2772.                         if (isnum(ch2)) ch1 = "1";
  2773.                 }
  2774.                 /*---------------------------------------------------------------------*/
  2775.                 /* ISURL                                                               */
  2776.                 /*---------------------------------------------------------------------*/
  2777.                 else if (!strcasecmp(param[0], "isurl"))
  2778.                 {
  2779.                         if (ap_is_url(ch2)) ch1 = "1";
  2780.                 }
  2781.                 /*---------------------------------------------------------------------*/
  2782.                 /* ISCB                                                                */
  2783.                 /*---------------------------------------------------------------------*/
  2784.                 else if (!strcasecmp(param[0], "iscb"))
  2785.                 {
  2786.                         if (nparam > 0)
  2787.                         {
  2788.                                 if (!strcasecmp(param[1], "visa")) x = 1;
  2789.                                 else if (!strncasecmp(param[1], "master", 6)) x = 1;
  2790.                                 else if (!strncasecmp(param[1], "amer", 4)) x = 2;
  2791.                                 else if (!strncasecmp(param[1], "novus", 5)) x = 2;
  2792.                                 else x = -1;
  2793.                         }
  2794.                         else x = 0;     /* Visa si pas de parametre */
  2795.        
  2796.                         if (x > -1)
  2797.                         {
  2798.                                 if (verif_cb(conf->pool_tag, x, ch2)) ch1 = "1";        /* VRAI */
  2799.                         }
  2800.                 }
  2801.                 /*---------------------------------------------------------------------*/
  2802.                 /* ISDIR...                                                            */
  2803.                 /*---------------------------------------------------------------------*/
  2804.                 else if (!strncasecmp(param[0], "isdir", 5))
  2805.                 {
  2806.                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(ch2, conf->r);
  2807.                         if (S_ISDIR (conf->rr->finfo.st_mode))  /* Oui, c'est un directory */
  2808.                         {
  2809.                                 if (nparam > 0)
  2810.                                 {
  2811.                                         x = strlen(param[1]);
  2812.                                         for (i = 0,z = F_OK; i < x; i++)
  2813.                                         {
  2814.                                                 if (param[1][i] == 'r' || param[1][i] == 'R') z |= R_OK;
  2815.                                                 else if (param[1][i] == 'w' || param[1][i] == 'W') z |= W_OK;
  2816.                                                 else if (param[1][i] == 'x' || param[1][i] == 'X') z |= X_OK;
  2817.                                         }
  2818.                                         if (access(conf->rr->filename, z) == 0) ch1 = "1";
  2819.                                 }
  2820.                                 else ch1 = "1"/* Le fichier exist */
  2821.                         }
  2822.                 }
  2823.                 /*---------------------------------------------------------------------*/
  2824.                 /* ISFILE                                                              */
  2825.                 /*---------------------------------------------------------------------*/
  2826.                 else if (!strcasecmp(param[0], "isfile"))
  2827.                 {
  2828.                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(ch2, conf->r);
  2829.                         if (S_ISREG(conf->rr->finfo.st_mode))   /* Oui, c'est un fichier */
  2830.                         {
  2831.                                 if (nparam > 0)
  2832.                                 {
  2833.                                         x = strlen(param[1]);
  2834.                                         for (i = 0,z = F_OK; i < x; i++)
  2835.                                         {
  2836.                                                 if (param[1][i] == 'r' || param[1][i] == 'R') z |= R_OK;
  2837.                                                 else if (param[1][i] == 'w' || param[1][i] == 'W') z |= W_OK;
  2838.                                                 else if (param[1][i] == 'x' || param[1][i] == 'X') z |= X_OK;
  2839.                                         }
  2840.                                         if (access(conf->rr->filename, z) == 0) ch1 = "1";
  2841.                                 }
  2842.                                 else ch1 = "1"/* Le fichier exist */
  2843.                         }
  2844.                 }
  2845.                 /*---------------------------------------------------------------------*/
  2846.                 /* ISLINK                                                              */
  2847.                 /*---------------------------------------------------------------------*/
  2848.                 else if (!strcasecmp(param[0], "islink"))
  2849.                 {
  2850.                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(ch2, conf->r);
  2851.                         if (S_ISLNK(conf->rr->finfo.st_mode)) ch1 = "1";        /* Oui, c'est un lien symbolique */
  2852.                 }
  2853.                 /*---------------------------------------------------------------------*/
  2854.                 /* ISEXEC...                                                           */
  2855.                 /*---------------------------------------------------------------------*/
  2856.                 else if (!strncasecmp(param[0], "isexec", 6))
  2857.                 {
  2858.                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(ch2, conf->r);
  2859.                         if (conf->rr->finfo.st_mode)
  2860.                         {
  2861.                                 if (access(conf->rr->filename, X_OK) == 0) ch1 = "1";
  2862.                         }
  2863.                 }
  2864.                 /*---------------------------------------------------------------------*/
  2865.                 /* ISREAD...                                                           */
  2866.                 /*---------------------------------------------------------------------*/
  2867.                 else if (!strncasecmp(param[0], "isread", 6))
  2868.                 {
  2869.                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(ch2, conf->r);
  2870.                         if (conf->rr->finfo.st_mode)
  2871.                         {
  2872.                                 if (access(conf->rr->filename, R_OK) == 0) ch1 = "1";
  2873.                         }
  2874.                 }
  2875.                 /*---------------------------------------------------------------------*/
  2876.                 /* ISWRITE...                                                          */
  2877.                 /*---------------------------------------------------------------------*/
  2878.                 else if (!strncasecmp(param[0], "iswrite", 7))
  2879.                 {
  2880.                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(ch2, conf->r);
  2881.                         if (conf->rr->finfo.st_mode)
  2882.                         {
  2883.                                 if (access(conf->rr->filename, W_OK) == 0) ch1 = "1";
  2884.                         }
  2885.                 }
  2886.                 /*---------------------------------------------------------------------*/
  2887.                 /* ISMASK...                                                           */
  2888.                 /*---------------------------------------------------------------------*/
  2889.                 else if (!strcasecmp(param[0], "ismask"))
  2890.                 {
  2891.                         if (nparam > 0) /* Il faut au moins 1 parametre */
  2892.                         {
  2893.                                 if (ap_checkmask(ch2, param[1])) ch1 = "1";     /* VRAI */
  2894.                         }
  2895.                 }
  2896.                 /*---------------------------------------------------------------------*/
  2897.                 /* ISBISSEX...                                                         */
  2898.                 /*---------------------------------------------------------------------*/
  2899.                 else if (!strncasecmp(param[0], "isbissex", 8))
  2900.                 {
  2901.                         if ((x = atoi(ch2)) > 0)
  2902.                         {
  2903.                                 if (annee_bissex(x)) ch1 = "1";
  2904.                         }
  2905.                 }
  2906.                 /*---------------------------------------------------------------------*/
  2907.                 /* ISREQPARENT                                                         */
  2908.                 /*---------------------------------------------------------------------*/
  2909.                 else if (!strcasecmp(param[0], "isreqparent"))
  2910.                 {
  2911.                         if (ap_is_initial_req(conf->r)) ch1 = "1";
  2912.                 }
  2913.                 /*---------------------------------------------------------------------*/
  2914.                 /* ISWORD...(n,n,n) et ISQWORD...(n,n,n)                               */
  2915.                 /*---------------------------------------------------------------------*/
  2916.                 else if (!strncasecmp(param[0], "isword", 6) || !strncasecmp(param[0], "isqword", 7))
  2917.                 {
  2918.                         if (nparam > 0) y = atoi(param[1]);     /* Numero du mot a recuperer */
  2919.                         if (nparam > 1) w = atoi(param[2]);     /* Taille minimum du mot */
  2920.                         if (nparam > 2) v = atoi(param[3]);     /* Taille maximum du mot */
  2921.        
  2922.                         if (!strncasecmp(param[0], "isq", 3)) flag = TRUE;      /* S'il faut prendre en compte les guillemets */
  2923.        
  2924.                         recupmots(conf->pool_tag, ch2, y, w, v, flag, 1, &x);
  2925.                         if (x) ch1 = "1";
  2926.                 }
  2927.         }
  2928.         /*---------------------------------------------------------------------*/
  2929.         /* IF...                                                               */
  2930.         /*---------------------------------------------------------------------*/
  2931.         else if (!strncasecmp(param[0], "if", 2))
  2932.         {
  2933.                 /* ---------- IF ---------- */
  2934.                 if (!strcasecmp(param[0], "if"))
  2935.                 {
  2936.                         if (nparam < 1) param[1] = ""/* Vide si pas de parametres  */
  2937.                         if (testlog(conf, ch2)) ch1 = param[1]; /* Si la condition est Vrai */
  2938.                         else if (nparam > 1) ch1 = param[2];    /* Si la condition est fausse */
  2939.                 }
  2940.         }
  2941.         /*---------------------------------------------------------------------*/
  2942.         /* CPAGE(n,n,n)                                                        */
  2943.         /*---------------------------------------------------------------------*/
  2944.         else if (!strncasecmp(param[0], "cpage", 5))
  2945.         {
  2946.                 if (nparam > 0)
  2947.                 {
  2948.                         w = atoi(param[1]);               /* Nombre total d'éléments */
  2949.                         v = (nparam > 1) ? atoi(param[2]) : 1/* Partitionnement : Nombre d'éléments par page */
  2950.                         if (v < 1) v = 1;
  2951.                         if (!strcasecmp(ch2, "npage"))
  2952.                         {
  2953.                                 y = w/v;
  2954.                                 if (w%v) y++;
  2955.                                 ch1 = ap_psprintf(conf->pool_tag, "%d", y);
  2956.                         }
  2957.                         else if (nparam > 2)    /* Positionnement : Premier élément de la page */
  2958.                         {
  2959.                                 x = atoi(param[3]);
  2960.                                 if (x < 0) x = 0;
  2961.                                 else if (x > w) x = w;
  2962.                                 if (!strcasecmp(ch2, "page")) ch1 = ap_psprintf(conf->pool_tag, "%d", (x / v) + 1);
  2963.                                 else if (!strncasecmp(ch2, "prev", 4))
  2964.                                 {
  2965.                                         if ((x - v) >= 0) ch1 = ap_psprintf(conf->pool_tag, "%d", x - v);
  2966.                                         else ch1 = "0";
  2967.                                 }
  2968.                                 else if (!strcasecmp(ch2, "next"))
  2969.                                 {
  2970.                                         if (x + v >= w) y = x;
  2971.                                         else y = x+v;
  2972.                                         ch1 = ap_psprintf(conf->pool_tag, "%d", y);
  2973.                                 }
  2974.                                 else if (!strcasecmp(ch2, "start")) ch1 = "0";
  2975.                                 else if (!strcasecmp(ch2, "end"))
  2976.                                 {
  2977.                                         y = w/v;
  2978.                                         if (w%v) y++;
  2979.                                         ch1 = ap_psprintf(conf->pool_tag, "%d", (y-1)*v);
  2980.                                 }
  2981.                                 else if (!strcasecmp(ch2, "isstart") || !strcasecmp(ch2, "ifstart"))
  2982.                                 {
  2983.                                         if (x > 0) ch1 = "0";
  2984.                                         else ch1 = "1";
  2985.                                 }
  2986.                                 else if (!strcasecmp(ch2, "isend") || !strcasecmp(ch2, "ifend"))
  2987.                                 {
  2988.                                         if ((x + v) >= w) ch1 = "1";
  2989.                                         else ch1 = "0";
  2990.                                 }
  2991.                         }
  2992.                 }
  2993.         }
  2994.         /*---------------------------------------------------------------------*/
  2995.         /* NBRWORD...(n,n) et NBRQWORD...(n,n)                                 */
  2996.         /*---------------------------------------------------------------------*/
  2997.         else if (!strncasecmp(param[0], "nbrword", 7) || !strncasecmp(param[0], "nbrqword", 8))
  2998.         {
  2999.                 if (nparam > 0) w = atoi(param[1]);     /* Taille minimum du mot */
  3000.                 if (nparam > 1) v = atoi(param[2]);     /* Taille maximum du mot */
  3001.  
  3002.                 if (!strncasecmp(param[0], "nbrq", 4)) flag = TRUE;     /* S'il faut prendre en compte les guillemets */
  3003.  
  3004.                 recupmots(conf->pool_tag, ch2, 1, w, v, flag, 2, &x);
  3005.                 ch1 = ap_psprintf(conf->pool_tag, "%d", x);     /* Nombre de mots trouve dans la chaine */
  3006.         }
  3007.         /*---------------------------------------------------------------------*/
  3008.         /* INTERP...                                                           */
  3009.         /*---------------------------------------------------------------------*/
  3010.         else if (!strncasecmp(param[0], "interp", 6))
  3011.         {
  3012.                 ch1 = interp(conf, ch2);
  3013.         }
  3014.         /*---------------------------------------------------------------------*/
  3015.         /* HEXTOINT...                                                         */
  3016.         /*---------------------------------------------------------------------*/
  3017.         else if (!strncasecmp(param[0],"hextoint", 8)) ch1 = ap_psprintf(conf->pool_tag, "%lu", strtol(ch2, NULL, 16));
  3018.         /*---------------------------------------------------------------------*/
  3019.         /* INTTOHEX...(n)                                                      */
  3020.         /*---------------------------------------------------------------------*/
  3021.         else if (!strncasecmp(param[0],"inttohex", 8))
  3022.         {
  3023.                 x = (nparam > 0) ? atoi(param[1]) : 0/* Pour fixer le nombre de caracteres */
  3024.                 ch1 = int_to_hex(conf->pool_tag, strtol(ch2, NULL, 10), x, NULL);
  3025.         }
  3026.         /*---------------------------------------------------------------------*/
  3027.         /* HEXTOSTR...                                                         */
  3028.         /*---------------------------------------------------------------------*/
  3029.         else if (!strncasecmp(param[0],"hextostr", 8))
  3030.         {
  3031.                 if ((y = strlen(ch2)-1) > 0)
  3032.                 {
  3033.                         ptr = ap_pcalloc(conf->pool_tag, 3 * sizeof(char));     /* Alloue de la memoire pour stocker 2 caracteres */
  3034.                         ch1 = ap_palloc(conf->pool_tag, (y+3) * sizeof(char))/* Alloue de la memoire pour le resultat */
  3035.                         for (x = 0, z = 0; x < y; x+=2)
  3036.                         {
  3037.                                 if (!isxdigit(ptr[0] = ch2[x]) || !isxdigit(ptr[1] = ch2[x+1])) break/* Si ce n'est pas une valeur hexa alors stop le traitement */
  3038.                                 ch1[z++] = (char)strtol(ptr, NULL, 16);
  3039.                         }
  3040.                         ch1[z] = '\0';
  3041.                 }
  3042.         }
  3043.         /*---------------------------------------------------------------------*/
  3044.         /* ORD                                                                 */
  3045.         /*---------------------------------------------------------------------*/
  3046.         else if (!strcasecmp(param[0],"ord"))
  3047.         {
  3048.                 if (nparam > 0) y = atoi(param[1]);
  3049.                 else y = 0;
  3050.  
  3051.                 if (y >= 0 && y < strlen(ch2)) ch1 = ap_psprintf(conf->pool_tag, "%u", (unsigned char)ch2[y]);
  3052.                 else ch1 = "0";
  3053.         }
  3054.         /*---------------------------------------------------------------------*/
  3055.         /* CHR                                                                 */
  3056.         /*---------------------------------------------------------------------*/
  3057.         else if (!strcasecmp(param[0], "chr"))
  3058.         {
  3059.                 y = atoi(ch2);
  3060.                 if (y > 0 && y < 256) ch1 = ap_psprintf(conf->pool_tag, "%c", (unsigned char)y);
  3061.         }
  3062.         /*---------------------------------------------------------------------*/
  3063.         /* BASETOINT...(n)                                                     */
  3064.         /*---------------------------------------------------------------------*/
  3065.         else if (!strncasecmp(param[0],"basetoint", 9)) ch1 = ap_psprintf(conf->pool_tag, "%lu", strtol(ch2, NULL, x = (nparam > 0) ? atoi(param[1]) : 0));
  3066.         /*---------------------------------------------------------------------*/
  3067.         /* STR...                                                              */
  3068.         /*---------------------------------------------------------------------*/
  3069.         else if (!strncasecmp(param[0], "str", 3))
  3070.         {
  3071.                 /*---------------------------------------------------------------------*/
  3072.                 /* STRTOHEX...                                                         */
  3073.                 /*---------------------------------------------------------------------*/
  3074.                 if (!strncasecmp(param[0],"strtohex", 8))
  3075.                 {
  3076.                         if ((y = strlen(ch2)) > 0)
  3077.                         {
  3078.                                 ch1 = ap_palloc(conf->pool_tag, (y * 2 * sizeof(char))+1);      /* Alloue un emplacement memoire pour le resultat */
  3079.                                 for (x = 0, z = 0; x < y; x++)
  3080.                                 {
  3081.                                         ptr = int_to_hex(conf->pool_tag, (long unsigned int)ch2[x], 2, NULL);
  3082.                                         ch1[z++] = ptr[0];      /* Recupere le premier caractere */
  3083.                                         ch1[z++] = ptr[1];      /* Recupere le deuxieme caractere */
  3084.                                 }
  3085.                                 ch1[z] = '\0'/* Fin de chaine */
  3086.                         }
  3087.                 }
  3088.                 /*---------------------------------------------------------------------*/
  3089.                 /* STRREPEAT                                                           */
  3090.                 /*---------------------------------------------------------------------*/
  3091.                 else if (!strcasecmp(param[0], "strrepeat"))
  3092.                 {
  3093.                         x = (nparam > 0) ? atoi(param[1]) : 0;
  3094.                         y = strlen(ch2);
  3095.        
  3096.                         if (x > 0 && y > 0)
  3097.                         {
  3098.                                 ptr = ch1 = ap_palloc(conf->pool_tag, (y * x) + 1);     /* Allocation de la zone memoire necessaire */
  3099.        
  3100.                                         while(x-- > 0)
  3101.                                 {
  3102.                                         memcpy(ptr, ch2, y);
  3103.                                         ptr += y;
  3104.                                 }
  3105.                                 ptr[0] = 0;     /* Fin de chaine */
  3106.                         }
  3107.                 }
  3108.                 /*---------------------------------------------------------------------*/
  3109.                 /* STRLEN...                                                           */
  3110.                 /*---------------------------------------------------------------------*/
  3111.                 else if (!strncasecmp(param[0], "strlen", 6)) ch1 = ap_psprintf(conf->pool_tag, "%lu", (long int)strlen(ch2));
  3112.                 /*---------------------------------------------------------------------*/
  3113.                 /* STRREV...                                                           */
  3114.                 /*---------------------------------------------------------------------*/
  3115.                 else if (!strncasecmp(param[0], "strrev", 6))
  3116.                 {
  3117.                         x = strlen(ch2) - 1;
  3118.  
  3119.                         for (y = 0; y < x; y++)
  3120.                         {
  3121.                                 car = ch2[y];
  3122.                                 ch2[y] = ch2[x];
  3123.                                 ch2[x--] = car;
  3124.                         }
  3125.  
  3126.                         ch1 = ch2;
  3127.                 }
  3128.                 /*---------------------------------------------------------------------*/
  3129.                 /* STRTR                                                               */
  3130.                 /*---------------------------------------------------------------------*/
  3131.                 else if (!strcasecmp(param[0], "strtr"))
  3132.                 {
  3133.                         if (nparam > 1 && (z = strlen(ch2)) > 0)
  3134.                         {
  3135.                                 if ((x = strlen(param[1])) > (y = strlen(param[2]))) x = y;     /* Recupere la longueur de From et To */
  3136.  
  3137.                                 for (i = 0; i < 256; tr[i] = i++);                                                            /* Remplit le tableau ASCII */
  3138.                                 for (i = 0; i < x; i++) tr[(unsigned char)param[1][i]] = param[2][i];   /* Modifie le tableau ASCII */
  3139.  
  3140.                                 for (i = 0; i < z; i++) ch2[i] = tr[(unsigned char)ch2[i]];
  3141.                         }
  3142.  
  3143.                         ch1 = ch2;
  3144.                 }
  3145.                 /* --------------------------------------------------- */
  3146.                 else if (nparam > 0)
  3147.                 {
  3148.                         /*---------------------------------------------------------------------*/
  3149.                         /* STRCHR                                                              */
  3150.                         /*---------------------------------------------------------------------*/
  3151.                         if (!strcasecmp(param[0], "strchr"))
  3152.                         {
  3153.                                 if (strlen(param[1]) > 0)
  3154.                                 {
  3155.                                         if ((temp = strchr(ch2, param[1][0])) != NULL) ch1 = temp;
  3156.                                 }
  3157.                         }
  3158.                         /*---------------------------------------------------------------------*/
  3159.                         /* STRRCHR                                                             */
  3160.                         /*---------------------------------------------------------------------*/
  3161.                         else if (!strcasecmp(param[0], "strrchr"))
  3162.                         {
  3163.                                 if (strlen(param[1]) > 0)
  3164.                                 {
  3165.                                         if ((temp = strrchr(ch2, param[1][0])) != NULL) ch1 = temp;
  3166.                                 }
  3167.                         }
  3168.                         /*---------------------------------------------------------------------*/
  3169.                         /* STRSTR                                                              */
  3170.                         /*---------------------------------------------------------------------*/
  3171.                         else if (!strcasecmp(param[0], "strstr"))
  3172.                         {
  3173.                                 if (strlen(param[1]) > 0)
  3174.                                 {
  3175.                                         if ((temp = strstr(ch2, param[1])) != NULL) ch1 = temp;
  3176.                                 }
  3177.                         }
  3178.                         /*---------------------------------------------------------------------*/
  3179.                         /* STRCUT... et STRCASECUT...                                          */
  3180.                         /*---------------------------------------------------------------------*/
  3181.                         else if (!strncasecmp(param[0], "strcut", 6) || !strncasecmp(param[0], "strcasecut", 10))
  3182.                         {
  3183.                                 if (nparam > 1)
  3184.                                 {
  3185.                                         if (!strcmp(param[2], "*")) x = -1;
  3186.                                         else x = atoi(param[2]);
  3187.                                 }
  3188.                                 else x = -1;
  3189.  
  3190.                                 if (!strncasecmp(param[0], "strcut", 6)) ch1 = strsup(ch2, param[1], x, 0);
  3191.                                 else ch1 = strsup(ch2, param[1], x, 1);
  3192.                         }
  3193.                         /*---------------------------------------------------------------------*/
  3194.                         /* STRREP... et STRCASEREP...                                          */
  3195.                         /*---------------------------------------------------------------------*/
  3196.                         else if (!strncasecmp(param[0], "strrep", 6) || !strncasecmp(param[0], "strcaserep", 10))
  3197.                         {
  3198.                                 if (nparam > 1)
  3199.                                 {
  3200.                                         if (nparam > 2)
  3201.                                         {
  3202.                                                 if (!strcmp(param[3], "*")) x = -1;
  3203.                                                 else x = atoi(param[3]);
  3204.                                         }
  3205.                                         else x = -1;
  3206.  
  3207.                                         if (!strncasecmp(param[0], "strrep", 6)) ch1 = strrep(conf->pool_tag, ch2, param[1], param[2], x, 0);
  3208.                                         else ch1 = strrep(conf->pool_tag, ch2, param[1], param[2], x, 1);
  3209.                                 }
  3210.                         }
  3211.                         /*---------------------------------------------------------------------*/
  3212.                         /* STREND(n) et STRCASEEND(n)                                          */
  3213.                         /*---------------------------------------------------------------------*/
  3214.                         else if (!strcasecmp(param[0], "strend") || !strcasecmp(param[0], "strcaseend"))
  3215.                         {
  3216.                                 if (nparam > 1)
  3217.                                 {
  3218.                                         if (!strcmp(param[2], "*")) x = -1;
  3219.                                         else x = atoi(param[2]);
  3220.                                 }
  3221.                                 else x = -1;
  3222.  
  3223.                                 if ((y = strlen(param[1])) > 0 && x != 0)
  3224.                                 {
  3225.                                         if (!strcasecmp(param[0], "strcaseend")) z = TRUE;      /* Ne fait pas la difference entre Maj/Min */
  3226.                                         else z = FALSE;
  3227.  
  3228.                                         v = w = 0;
  3229.                                         i = -1;
  3230.                                         while(ch2[++i] != '\0')
  3231.                                         {
  3232.                                                 if ((z && !strncasecmp(&ch2[i], param[1], y)) || (!z && !strncmp(&ch2[i], param[1], y)))
  3233.                                                 {
  3234.                                                         w = i;  /* Memorise la position de cette occurence */
  3235.                                                         if (++v == x) break;
  3236.                                                 }
  3237.                                         }
  3238.  
  3239.                                         if (w) ch2[w] = 0;      /* Fin de chaine */
  3240.                                 }
  3241.                                 ch1 = ch2;
  3242.                         }
  3243.                 }
  3244.         }
  3245.         /*---------------------------------------------------------------------*/
  3246.         /* SOUNDEX                                                             */
  3247.         /*---------------------------------------------------------------------*/
  3248.         else if (!strcasecmp(param[0], "soundex"))
  3249.         {
  3250.                 x = 0/* francais par defaut */
  3251.                 if (nparam > 0) /* Si il y a un parametre (la langue) */
  3252.                 {
  3253.                         if (!strcasecmp(param[1], "en")) x = 1/* Anglais */
  3254.                 }
  3255.  
  3256.                 ch1 = calcul_soundex(conf->pool_tag, ch2, x);
  3257.         }
  3258.         /*---------------------------------------------------------------------*/
  3259.         /* MD5                                                                 */
  3260.         /*---------------------------------------------------------------------*/
  3261.         else if (!strcasecmp(param[0],"md5")) ch1 = (char *)ap_md5(conf->pool_tag, (unsigned char *)ch2);
  3262.         /*---------------------------------------------------------------------*/
  3263.         /* CRC32...                                                            */
  3264.         /*---------------------------------------------------------------------*/
  3265.         else if (!strncasecmp(param[0], "crc32", 5))
  3266.         {
  3267.                 /* ---------- CRC32 ---------- */
  3268.                 if (!strcasecmp(param[0], "crc32")) ch1 = ap_psprintf(conf->pool_tag, "%lu", calcul_crc32(ch2));        /* Calcul le CRC32 de la chaine */
  3269.                 /* ---------- CRC32HEX... ---------- */
  3270.                 else if (!strncasecmp(param[0], "crc32hex", 8)) ch1 = int_to_hex(conf->pool_tag, calcul_crc32(ch2), 8, NULL);   /* Calcul le CRC32 de la chaine en hexadecimal */
  3271.                 /* ---------- CRC32ENCOD... ---------- */
  3272.                 else if (!strncasecmp(param[0], "crc32encod", 10))
  3273.                 {
  3274.                         if (nparam < 1) param[1] = NULL;
  3275.                         ch1 = encode_crc32(conf->pool_tag, ch2, param[1]);
  3276.                 }
  3277.                 /* ---------- CRC32DECOD... ---------- */
  3278.                 else if (!strncasecmp(param[0], "crc32decod", 10))
  3279.                 {
  3280.                         if (nparam < 1) param[1] = NULL;
  3281.                         if ((temp = decode_crc32(conf->pool_tag, ch2, param[1])) != NULL) ch1 = temp;
  3282.                 }
  3283.                 /* ---------- CRC32VERIF... ---------- */
  3284.                 else if (!strncasecmp(param[0], "crc32verif", 10))
  3285.                 {
  3286.                         if (nparam < 1) param[1] = NULL;
  3287.                         if ((temp = decode_crc32(conf->pool_tag, ch2, param[1])) != NULL) ch1 = "1";
  3288.                         else ch1 = "0";
  3289.                 }
  3290.         }
  3291.         /*---------------------------------------------------------------------*/
  3292.         /* BASE64ENCOD...                                                      */
  3293.         /*---------------------------------------------------------------------*/
  3294.         else if (!strncasecmp(param[0], "base64encod", 11)) ch1 = base64encode(conf->pool_tag, ch2, strlen(ch2), NULL);
  3295.         /*---------------------------------------------------------------------*/
  3296.         /* BASE64DECOD...                                                      */
  3297.         /*---------------------------------------------------------------------*/
  3298.         else if (!strncasecmp(param[0], "base64decod", 11))
  3299.         {
  3300.                 if ((temp = base64decode(conf->pool_tag, ch2, strlen(ch2), NULL)) != NULL) ch1 = temp;
  3301.         }
  3302.         /*---------------------------------------------------------------------*/
  3303.         /*---------------------------------------------------------------------*/
  3304.         /* CONST...                                                            */
  3305.         /*---------------------------------------------------------------------*/
  3306.         else if (!strncasecmp(param[0],"const", 5))
  3307.         {
  3308.                 if (!strcasecmp(ch2, "server_built")) ch1 = ap_pstrdup(conf->pool_tag, ap_get_server_built())/* Renvoi la date et heure de la derniere compilation du serveur */
  3309.                 else if (!strcasecmp(ch2, "remote_user")) ch1 = ap_pstrdup(conf->pool_tag, conf->r->connection->user)/* Renvoi le nom du User authentifie s'il y en a un */
  3310.                 else if (!strcasecmp(ch2, "server_version")) ch1 = ap_pstrdup(conf->pool_tag, ap_get_server_version())/* Renvoi le numero de version du serveur */
  3311.                 else if (!strcasecmp(ch2, "id") || !strcasecmp(ch2, "unique_id")) ch1 = ap_pstrdup(conf->pool_tag, conf->unique_id);    /* Renvoi un numero unique */
  3312.                 else if (!strcasecmp(ch2, "remote_host")) ch1 = ap_pstrdup(conf->pool_tag, ap_get_remote_host(conf->r->connection, conf->r->per_dir_config, REMOTE_NAME));      /* Renvoi le remote_host */
  3313.                 else if (!strcasecmp(ch2, "document_root")) ch1 = ap_pstrdup(conf->pool_tag, ap_document_root(conf->r));        /* Renvoi le document_root */
  3314.                 else if (!strcasecmp(ch2, "server_name")) ch1 = ap_pstrdup(conf->pool_tag, ap_get_server_name(conf->r));        /* Renvoi le server_name */
  3315.                 else if (!strcasecmp(ch2, "document_uri")) ch1 = conf->r->uri;  /* Renvoi l'URI du document principal */
  3316.                 else if (!strcasecmp(ch2, "localhost")) ch1 = ap_get_local_host(conf->pool_tag);        /* Renvoi le localHost */
  3317.                 else if (!strcasecmp(ch2, "boundary")) ch1 = conf->boundary;    /* Renvoi le boundary ou une chaine vide s'il n'y en a pas */
  3318.                 else if (!strcasecmp(ch2, "adml_version")) ch1 = ADML_VERSION;  /* Renvoi le numero de version de ADML */
  3319.                 else if (!strcasecmp(ch2, "adml_name")) ch1 = ADML_NOM; /* Renvoi le nom du programme (module) ADML */
  3320.                 else if (!strcasecmp(ch2, "document_name"))     /* Renvoi le nom du document principal */
  3321.                 {
  3322.             if ((ptr = strrchr(conf->r->filename, '/'))) ch1 = ++ptr;
  3323.             else ch1 = conf->r->uri;
  3324.                 }
  3325.                 else if (!strcasecmp(ch2, "cr")) ch1 = "\r";    /* Renvoi un caractere de fin de ligne */
  3326.                 else if (!strcasecmp(ch2, "lf")) ch1 = "\n";    /* Renvoi un caractere de nouvelle ligne */
  3327.                 else if (!strcasecmp(ch2, "crlf")) ch1 = "\r\n";        /* Renvoi un caractere de fin de ligne et nouvelle ligne */
  3328.         }
  3329.         /*---------------------------------------------------------------------*/
  3330.         /* VAR...                                                              */
  3331.         /*---------------------------------------------------------------------*/
  3332.         else if (!strncasecmp(param[0],"var", 3))
  3333.         {
  3334.                 if (!strcasecmp(ch2, "ligne") || !strcasecmp(ch2, "line")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->ligne);        /* Renvoi le numero de ligne courante du fichier en cour */
  3335.                 else if (!strcasecmp(ch2, "ifshow"))
  3336.                 {
  3337.                         if (if_sortie) ch1 = "1";       /* Oui! la sortie est autorise */
  3338.                         else ch1 = "0";
  3339.                 }
  3340.                 else if (!strncasecmp(ch2, "ifnoheader", 10))
  3341.                 {
  3342.                         if (conf->noheader) ch1 = "1";
  3343.                         else ch1 = "0";
  3344.                 }
  3345.                 else if (!strncasecmp(ch2, "ifheader", 8))
  3346.                 {
  3347.                         if (conf->header) ch1 = "1";
  3348.                         else ch1 = "0";
  3349.                 }
  3350.                 else if (!strncasecmp(ch2, "ifinc", 5))
  3351.                 {
  3352.                         if (conf->fichier != NULL) ch1 = "1";   /* Oui! ont est dans un Include */
  3353.                         else ch1 = "0";
  3354.                 }
  3355.                 else if (!strcasecmp(ch2, "document_name"))
  3356.                 {
  3357.                         if (conf->filename == NULL)     /* Si ont est dans le document principal */
  3358.                         {
  3359.                 if ((ptr = strrchr(conf->r->filename, '/'))) ch1 = ++ptr;
  3360.                 else ch1 = conf->r->uri;
  3361.                         }
  3362.                         else
  3363.                         {
  3364.                 if ((ptr = strrchr(conf->filename, '/'))) ch1 = ++ptr;
  3365.                 else ch1 = ap_pstrdup(conf->pool_tag, conf->filename);
  3366.                         }
  3367.                 }
  3368.         }
  3369.         /*---------------------------------------------------------------------*/
  3370.         /* ENV                                                                 */
  3371.         /*---------------------------------------------------------------------*/
  3372.         else if (!strcasecmp(param[0],"env"))
  3373.         {
  3374.                 if ((conf->ctemp = ap_table_get(conf->r->subprocess_env, ch2)) != NULL) ch1 = ap_pstrdup(conf->pool_tag, conf->ctemp);
  3375.  
  3376. /*
  3377.                 arr = ap_table_elts(r->subprocess_env);
  3378.                 elts = (table_entry *) arr->elts;
  3379.  
  3380.                 for(y=0; y < arr->nelts; y++)
  3381.                 {
  3382.                         if (!strcasecmp(elts[y].key, ch2))
  3383.                         {
  3384.                                 ch1 = elts[y].val;
  3385.                                 break;
  3386.                         }
  3387.                 }
  3388. */
  3389.         }
  3390.         /*---------------------------------------------------------------------*/
  3391.         /* WHILE                                                               */
  3392.         /*---------------------------------------------------------------------*/
  3393.         else if (!strcasecmp(param[0],"while"))
  3394.         {
  3395.                 ch1 = "0";      /* Valeur de retour par defaut */
  3396.                 if (conf->nwhile > 0)   /* Si on est dans une boucle ou un if, ... */
  3397.                 {
  3398.                         for (y=conf->nwhile; y > 0; y--)
  3399.                         {
  3400.                                 if (conf->ifwhile[y].type > 2) break;   /* Recherche une boucle While et ecarte les IF afin de prendre la boucle la plus proche */
  3401.                         }
  3402.  
  3403.                         if (!strcasecmp(ch2, "loop")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->ifwhile[y].tour);   /* Renvoi le nombre de boucle effectue */
  3404.                         else if (!strcasecmp(ch2, "limit")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->ifwhile[y].limite);   /* Renvoi la valeur limit configurer dans le while */
  3405.                         else if (!strncasecmp(ch2, "istop", 5)) /* IsTop : Renvoi 1 (True) si ont est en haut de la boucle et 0 sinon */
  3406.                         {
  3407.                                 if (conf->ifwhile[y].tour < 1) ch1="1";
  3408.                         }
  3409.                         else if (!strncasecmp(ch2, "isbot", 5)) /* IsBottom : Renvoi 1 (True) si ont est en bas de la boucle et 0 sinon */
  3410.                         {
  3411.                                 if ((conf->ifwhile[y].tour + 1) < conf->ifwhile[y].limite || conf->ifwhile[y].limite < 1)
  3412.                                 {
  3413.                                         switch(conf->ifwhile[y].type)
  3414.                                         {
  3415.                                         /* ----- Type If ----- */
  3416.                                         case 1/* Erreur a prevoir */
  3417.                                         case 2/* Idem */
  3418.                                                 break;
  3419.                                         /* ----- Type Mysql / MysqlRows ----- */
  3420.                                         case 3: if ((conf->base_mysql[conf->ifwhile[y].num].numligne + 1) >= mysql_num_rows(conf->base_mysql[conf->ifwhile[y].num].res)) ch1="1";
  3421.                                                 break;
  3422.                                         /* ----- Type MysqlFields ----- */
  3423.                                         case 4: if ((conf->base_mysql[conf->ifwhile[y].num].numcolonne + 1) >= mysql_num_fields(conf->base_mysql[conf->ifwhile[y].num].res)) ch1="1";
  3424.                                                 break;
  3425.                                         /* ----- Type Upload ----- */
  3426.                                         case 5: if (conf->upload_num >= conf->nupload) ch1="1";
  3427.                                                 break;
  3428.                                         /* ----- Type Header ----- */
  3429.                                         case 6: if ((conf->headers_in_num + 1) >= conf->ifwhile[y].arr->nelts) ch1="1";
  3430.                                                 break;
  3431.                                         /* ----- Type Form ----- */
  3432.                                         case 7: if ((conf->form[conf->ifwhile[y].num].pos + 1) >= conf->ifwhile[y].arr->nelts) ch1="1";
  3433.                                                 break;
  3434.                                         /* ----- Type Cookie ----- */
  3435.                                         case 8: if ((conf->cookies.pos + 1) >= conf->ifwhile[y].arr->nelts) ch1="1";
  3436.                                                 break;
  3437.                                         default: break;
  3438.                                         }
  3439.                                 }
  3440.                                 else ch1 = "1"/* Si ont arrive a la valeur limite du nbr de boucle */
  3441.                         }
  3442.                 }
  3443.         }
  3444.         /*---------------------------------------------------------------------*/
  3445.         /* ESC...                                                              */
  3446.         /*---------------------------------------------------------------------*/
  3447.         else if (!strncasecmp(param[0],"esc", 3))
  3448.         {
  3449.                 /* ---------- ESCHTML ---------- */
  3450.                 if (!strcasecmp(param[0],"eschtml")) ch1 = ap_escape_html(conf->pool_tag, ch2)/* Retourne l'HTML protege */
  3451.         }
  3452.         /*---------------------------------------------------------------------*/
  3453.         /* BKSL_UNESC...                                                       */
  3454.         /*---------------------------------------------------------------------*/
  3455.         else if (!strncasecmp(param[0],"bksl_unesc", 10))
  3456.         {
  3457.                 ch1 = unescape_backslash(ch2)/* Convertit les anti-slash quelque choses */
  3458.         }
  3459.         /*---------------------------------------------------------------------*/
  3460.         /* DATE                                                                */
  3461.         /*---------------------------------------------------------------------*/
  3462.         else if (!strncasecmp(param[0],"date", 4))
  3463.         {
  3464.                 x = (nparam > 0) ? atoi(param[1]) : 0;
  3465.                 y = 0/* Francais par defaut */
  3466.                 if (nparam > 1) /* Choix de la langue */
  3467.                 {
  3468.                         if (!strncasecmp(param[2], "a_fr", 3)) y = 1;      /* Abreviation Francais */
  3469.                         else if (!strncasecmp(param[2], "en", 2)) y = 2;        /* Anglais */
  3470.                         else if (!strncasecmp(param[2], "a_en", 2)) y = 3;      /* Abreviation Anglais */
  3471.                 }
  3472.  
  3473.                 if (x < N_DATE && x > -1)       /* Si le numero de structure est correct */
  3474.                 {
  3475.                         temps = localtime(&conf->secs[x]);
  3476.                        
  3477.                         if (!strcasecmp(ch2, "month")) ch1 = ap_psprintf(conf->pool_tag, "%02.d", temps->tm_mon+1);
  3478.                         else if (!strcasecmp(ch2, "day")) ch1 = ap_psprintf(conf->pool_tag, "%02.d", temps->tm_mday);
  3479.                         else if (!strncasecmp(ch2, "dayweek", 7))
  3480.                         {
  3481.                                 /* Afin de conserver une coerrence entre le Francais et l'anglais, la semaine commence a 1 (dimanche) pour toutes les langues */
  3482.                                 ch1 = ap_psprintf(conf->pool_tag, "%d", temps->tm_wday+1);
  3483.                         }
  3484.                         else if (!strcasecmp(ch2, "year")) ch1 = ap_psprintf(conf->pool_tag, "%04.d", temps->tm_year+1900);
  3485.                         else if (!strncasecmp(ch2, "hour",4)) ch1 = ap_psprintf(conf->pool_tag, "%02.d", temps->tm_hour);
  3486.                         else if (!strncasecmp(ch2, "min", 3)) ch1 = ap_psprintf(conf->pool_tag, "%02.d", temps->tm_min);
  3487.                         else if (!strncasecmp(ch2, "sec", 3)) ch1 = ap_psprintf(conf->pool_tag, "%02.d", temps->tm_sec);
  3488.                         else if (!strcasecmp(ch2, "dayname")) ch1 = ap_pstrdup(conf->pool_tag, jour[y][temps->tm_wday]);
  3489.                         else if (!strcasecmp(ch2, "monthname")) ch1 = ap_pstrdup(conf->pool_tag, mois[y][temps->tm_mon]);
  3490.                         else if (!strcasecmp(ch2, "yearday")) ch1 = ap_psprintf(conf->pool_tag, "%04.d", jour_annee(temps->tm_mday, temps->tm_mon, temps->tm_year+1900));
  3491.                         /* ---------- TIMESTAMP (Date de la structure) ---------- */
  3492.                         else if (!strncasecmp(ch2, "time", 4)) ch1 = ap_psprintf(conf->pool_tag, "%lu", conf->secs[x]);
  3493.                         /* ---------- CURRENT_TIMESTAMP (date courante au format Unix) ---------- */
  3494.                         else if (!strncasecmp(ch2, "current_time", 12))
  3495.                         {
  3496.                                 time(&timestamp);
  3497.                                 ch1 = ap_psprintf(conf->pool_tag, "%lu", timestamp);
  3498.                         }
  3499.                 }
  3500.         }
  3501.         /*---------------------------------------------------------------------*/
  3502.         /* DAYWEEK...                                                          */
  3503.         /*---------------------------------------------------------------------*/
  3504.         else if (!strncasecmp(param[0], "dayweek", 7))
  3505.         {
  3506.                 v = (nparam > 0) ? atoi(param[1]) : 1/* Jour */
  3507.                 w = (nparam > 1) ? atoi(param[2]) : 1/* Mois */
  3508.                 x = (nparam > 2) ? atoi(param[3]) : 1/* Annee */
  3509.  
  3510.                 if (v > 0 && v < 32 && w > 0 && w < 13)
  3511.                 {
  3512.                         if (!strncasecmp(ch2, "num", 3)) y = -1;                /* Numerique */
  3513.                         else if (!strncasecmp(ch2, "fr", 3)) y = 0;          /* Francais */
  3514.                         else if (!strncasecmp(ch2, "a_fr", 3)) y = 1;      /* Abreviation Francais */
  3515.                         else if (!strncasecmp(ch2, "en", 2)) y = 2;     /* Anglais */
  3516.                         else if (!strncasecmp(ch2, "a_en", 2)) y = 3;   /* Abreviation Anglais */
  3517.                         else y = -10;   /* Francais par defaut */
  3518.  
  3519.                         if (y >= 0) ch1 = ap_psprintf(conf->pool_tag, "%s", jour[y][jour_semaine(v, w, x)]);
  3520.                         else if (y == -1) ch1 = ap_psprintf(conf->pool_tag, "%d", jour_semaine(v, w, x)+1);
  3521.                 }
  3522.         }
  3523.         /*---------------------------------------------------------------------*/
  3524.         /* MONTHDAY                                                            */
  3525.         /*---------------------------------------------------------------------*/
  3526.         else if (!strcasecmp(param[0], "monthday"))
  3527.         {
  3528.                 v = (nparam > 0) ? atoi(param[1]) : 1/* Mois */
  3529.                 if (v > 0 && v < 13 && (w = atoi(ch2)) > 0) ch1 = ap_psprintf(conf->pool_tag, "%d", jour_dans_mois[annee_bissex(w)][v]);        /* Renvoi le nombre de jour du mois en question */
  3530.         }
  3531.         /*---------------------------------------------------------------------*/
  3532.         /* YEARDAY                                                             */
  3533.         /*---------------------------------------------------------------------*/
  3534.         else if (!strcasecmp(param[0], "yearday"))
  3535.         {
  3536.                 v = (nparam > 0) ? atoi(param[1]) : 0/* Jour */
  3537.                 w = (nparam > 1) ? atoi(param[2]) : 0/* Mois */
  3538.                 x = (nparam > 2) ? atoi(param[3]) : 0/* Annee */
  3539.  
  3540.                 if (v > 0 && v < 32 && w > 0 && w < 13 && x > 0) ch1 = ap_psprintf(conf->pool_tag, "%d", jour_annee(v, w, x));
  3541.         }
  3542.         /*---------------------------------------------------------------------*/
  3543.         /* MYSQL                                                               */
  3544.         /*---------------------------------------------------------------------*/
  3545.         else if (!strcasecmp(param[0],"mysql"))
  3546.         {
  3547.                 x = (nparam > 0) ? atoi(param[1]) : conf->mysql_def;
  3548.  
  3549.                 if (x < N_MYSQL && x > -1)      /* Si le numero de structure est correct */
  3550.                 {
  3551.                         /* ---------- Si c'est un mot cles ---------- */
  3552.                         if (!strcasecmp(ch2, "_hostinfo")) ch1 = mysql_get_host_info(&conf->base_mysql[x].mysql);
  3553.                         else if (!strcasecmp(ch2, "_clientinfo")) ch1 = mysql_get_client_info();
  3554.                         else if (!strcasecmp(ch2, "_error")) ch1 = md_mysql_error(&conf->base_mysql[x]);
  3555.                         else if (!strncasecmp(ch2, "_iserr", 6) || !strncasecmp(ch2, "_iferr", 6))
  3556.                         {
  3557.                                 if (conf->base_mysql[x].ferror) ch1 = "1";      /* Oui, il y a une erreur */
  3558.                                 else ch1 = "0"/* Pas d'erreur */
  3559.                         }
  3560.                         else if (!strncasecmp(ch2, "_isnoerr", 8) || !strncasecmp(ch2, "_ifnoerr", 8))
  3561.                         {
  3562.                                 if (conf->base_mysql[x].ferror) ch1 = "0"/* NON, il y a une erreur */
  3563.                                 else ch1 = "1"; /* Oui, il n'y a pas d'erreur */
  3564.                         }
  3565.                         /* ---------- Si une connection est OK ---------- */
  3566.                         else if (conf->base_mysql[x].fconnect)
  3567.                         {
  3568.                                 if (!strcasecmp(ch2, "_protoinfo")) ch1 = ap_psprintf(conf->pool_tag, "%d", mysql_get_proto_info(&conf->base_mysql[x].mysql));
  3569.                                 else if (!strcasecmp(ch2, "_serverinfo")) ch1 = mysql_get_server_info(&conf->base_mysql->mysql);
  3570.                                 else if (!strcasecmp(ch2, "_stat")) ch1 = mysql_stat(&conf->base_mysql[x].mysql);
  3571.                                 else if (!strcasecmp(ch2, "_id")) ch1 = ap_psprintf(conf->pool_tag, "%d", mysql_insert_id(&conf->base_mysql[x].mysql));
  3572.                                 /* ---------- Si une Requete est OK ---------- */
  3573.                                 else if (conf->base_mysql[x].fquery)
  3574.                                 {
  3575.                                         if (!strcasecmp(ch2, "_dataseek")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->base_mysql[x].numligne);
  3576.                                         else if (!strcasecmp(ch2, "_fieldseek")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->base_mysql[x].numcolonne);
  3577.                                         else if (!strncasecmp(ch2, "_nbrrow", 7) || !strncasecmp(ch2, "_nrow", 5)) ch1 = ap_psprintf(conf->pool_tag, "%d", mysql_num_rows(conf->base_mysql[x].res));
  3578.                                         else if (!strncasecmp(ch2, "_nbrfield", 9) || !strncasecmp(ch2, "_nfield", 7)) ch1 = ap_psprintf(conf->pool_tag, "%d", mysql_num_fields(conf->base_mysql[x].res));
  3579.                                         /* ---------- */
  3580.                                         else if (conf->base_mysql[x].numligne < 0 || conf->base_mysql[x].numligne >= md_mysql_nbrrows(&conf->base_mysql[x]))    /* Si ont est hors champs */
  3581.                                         {
  3582.                                                 ch1 = "";
  3583.                                         }
  3584.                                         else    /* Recherche du nom */
  3585.                                         {
  3586.                                                 w = -1/* Par defaut */
  3587.                                                 if (ch2[0] != '#')      /* Recherche en nom */
  3588.                                                 {
  3589.                                                         if ((conf->temp = strchr(ch2, '.')))
  3590.                                                         {
  3591.                                                                 conf->temp[0] = '\0';
  3592.                                                         }
  3593.  
  3594.                                                         z =-1;
  3595.                                                         while(++z < md_mysql_nbrfields(&conf->base_mysql[x]))
  3596.                                                         {
  3597.                                                                 if (md_mysql_fieldseek(&conf->base_mysql[x], z))
  3598.                                                                 {
  3599.                                                                         if (conf->temp) /* Controle du nom de la table egalement */
  3600.                                                                         {
  3601.                                                                                 if (!strcmp(conf->base_mysql[x].field->name, &conf->temp[1]) && !strcmp(conf->base_mysql[x].field->table, ch2)) break/* OK! c'est trouve! */
  3602.                                                                         }
  3603.                                                                         else
  3604.                                                                         {
  3605.                                                                                 if (!strcmp(ch2, conf->base_mysql[x].field->name)) break;       // OK! c'est trouve!
  3606.                                                                         }
  3607.                                                                 }
  3608.                                                         }
  3609.        
  3610.                                                         if (z < md_mysql_nbrfields(&conf->base_mysql[x])) w = z;        /* Trouver le champ */
  3611.                                                 }
  3612.                                                 else if (!strcmp(ch2, "#"))     /* Prend le champ courant */
  3613.                                                 {
  3614.                                                         if (conf->base_mysql[x].numcolonne >= 0 && conf->base_mysql[x].numcolonne < md_mysql_nbrfields(&conf->base_mysql[x])) w = conf->base_mysql[x].numcolonne;       /* Recupere le numero du champ courant */
  3615.                                                 }
  3616.                                                 else if (isnum(&ch2[1]) && strlen(&ch2[1]) > 0) /* Recherche avec le numero du champ */
  3617.                                                 {
  3618.                                                         z = atoi(&ch2[1]);
  3619.                                                         if (z >= 0 && z < md_mysql_nbrfields(&conf->base_mysql[x]))     w = z;       /* le champ numero z existe */
  3620.                                                 }
  3621.  
  3622.                                                 if (w > -1)     /* Si un champ est a renvoyer */
  3623.                                                 {
  3624.                                                         md_mysql_fieldseek(&conf->base_mysql[x], w);
  3625.                                                         if (nparam > 1)
  3626.                                                         {
  3627.                                                                 if (!strncasecmp(param[2], "val", 3) || strlen(param[2]) < 1) ch1 = conf->base_mysql[x].row[w]/* Renvoi la valeur du champ */
  3628.                                                                 else if (!strcasecmp(param[2], "name") || !strcasecmp(param[2], "nom")) ch1 = conf->base_mysql[x].field->name;  /* Renvoi le nom du champ */
  3629.                                                                 else if (!strncasecmp(param[2], "table", 5)) ch1 = conf->base_mysql[x].field->table;    /* Renvoi le nom de la table */
  3630.                                                                 else if (!strncasecmp(param[2], "def", 3)) ch1 = conf->base_mysql[x].field->def;        /* Renvoi la valeur par defaut du champ */
  3631.                                                                 else if (!strcasecmp(param[2], "type")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->base_mysql[x].field->type);       /* Renvoi le numero du type de champ */
  3632. /* -------------> a finir (typename et flagname */
  3633.                                                                 else if (!strcasecmp(param[2], "typename") || !strcasecmp(param[2], "typenom")) ch1 = ap_psprintf(conf->pool_tag, "%d", conf->base_mysql[x].field->type);       /* Renvoi le nom du type du champ */
  3634.                                                                 else if (!strncasecmp(param[2], "len", 3) || !strcasecmp(param[2], "taille")) ch1 = ap_psprintf(conf->pool_tag, "%u", conf->base_mysql[x].field->length);       /* Renvoi la taille du type du champ */
  3635.                                                                 else if (!strncasecmp(param[2], "maxlen", 6)) ch1 = ap_psprintf(conf->pool_tag, "%u", conf->base_mysql[x].field->max_length);   /* Renvoi la taille max de selected set du champ */
  3636.                                                                 else if (!strncasecmp(param[2], "flag", 4)) ch1 = ap_psprintf(conf->pool_tag, "%u", conf->base_mysql[x].field->flags)/* Renvoi la valeur de flag du champ */
  3637.                                                                 else if (!strncasecmp(param[2], "dec", 3)) ch1 = ap_psprintf(conf->pool_tag, "%u", conf->base_mysql[x].field->decimals);        /* Renvoi le nombre de decimal du champ */
  3638.                                                         }
  3639.                                                         else ch1 = conf->base_mysql[x].row[w]/* Renvoi la valeur du champ */
  3640.                                                 }
  3641.                                         }
  3642.                                 }
  3643.                         }
  3644.                 }
  3645.         }
  3646.         /*---------------------------------------------------------------------*/
  3647.         /* FONCTION INCONNU                                                    */
  3648.         /*---------------------------------------------------------------------*/
  3649.         else if (!strcasecmp(param[0],"right") || !strcasecmp(param[0],"left"))
  3650.         {
  3651.                 /* A voir (option) */
  3652.         }
  3653.  
  3654.         if (ch1 == NULL) ch1 = "";      /* Au cas ou */
  3655.  
  3656.         return(ch1);
  3657. }
  3658.  
  3659. /*--------------------------------------------------------------------------*/
  3660. /* Analyse une chaine  pour les calculs et test logique */
  3661. /*--------------------------------------------------------------------------*/
  3662. static char *calcul(adml_cfg *conf, const char *chaine)
  3663. {
  3664.         int ncalc = 0;
  3665.         adml_calcul tabcalc[15];
  3666.         int pos = 0, taille, parenth = 0, fparenth = 0;
  3667.         int sous_pos = 0, num = 0, debut, encour = FALSE, fin = -1;
  3668.         int signe;
  3669.         char guil = '\0';
  3670.         char *erreur = NULL, *ptr;
  3671.         double tempo;
  3672.  
  3673.         if (chaine == NULL) return("")/* Renvoi une chaine vide */
  3674.  
  3675.         if ((taille = strlen(chaine)) < 1) return("")/* Recupere la taille de la chaine et retourne "" si la chaine est vide */
  3676.  
  3677. /*
  3678. ap_rprintf(conf->r,"<P><B>DEBUT=[<TT>%s</TT>]</B> :<BR>", chaine);
  3679. */
  3680.         do
  3681.         {
  3682.                 if (fparenth > 0)       /* Si ont est dans une fonction */
  3683.                 {
  3684.                         if (chaine[pos] == '(') fparenth++;
  3685.                         else if (chaine[pos] == ')') fparenth--;
  3686.                 }
  3687.                 else    /* Si ont est pas dans une fonction */
  3688.                 {
  3689.                         if (guil == '\0')       /* Si les guillement ne sont pas encore ouvert */
  3690.                         {
  3691.                                 if (parenth > 0)        /* Si ont est dans une parenthese */
  3692.                                 {
  3693.                                         if (chaine[pos] == ')')
  3694.                                         {
  3695.                                                 parenth--;
  3696.                                                 if (parenth < 1)
  3697.                                                 {
  3698.                                                         if (pos - sous_pos > 0)
  3699.                                                         {
  3700.                                                                 signe = 0;
  3701.                                                                 conf->temp = calcul(conf, ap_pstrndup(conf->pool_tag, &chaine[sous_pos], pos - sous_pos));      /* Lance un sous-calcul */
  3702.                                                                 if (!strncmp(conf->temp, "Error:", 6)) return(conf->temp);
  3703.                                                                 else if (!strcmp(conf->temp, "-VaL*"))  /* C'est une valeur numerique */
  3704.                                                                 {
  3705.                                                                         tabcalc[ncalc].type = -2;
  3706.                                                                         tabcalc[ncalc].valeur = conf->calcul;
  3707.                                                                 }
  3708.                                                                 else    /* si c'est une chaine */
  3709.                                                                 {
  3710.                                                                         tabcalc[ncalc].type = 0;
  3711.                                                                         tabcalc[ncalc].chaine = conf->temp;
  3712.                                                                 }
  3713.                                                                 goto TRAITE_CHAINE;
  3714.                                                         }
  3715.                                                         else
  3716.                                                         {
  3717.                                                                 erreur = "Parenthese vide !";
  3718.                                                                 break;
  3719.                                                         }
  3720.                                                 }
  3721.                                         }
  3722.                                         else if (chaine[pos] == '(')
  3723.                                         {
  3724.                                                 if (chaine[pos - 1] == '$') fparenth++; /* Ont entre dans une fonction */
  3725.                                                 else parenth++; /* Si c'est une parenthese de priorite */
  3726.                                         }
  3727.                                 }
  3728.                                 else    /* Ont est pas dans une parenthese (sous-calcul) */
  3729.                                 {
  3730.                                         if (chaine[pos] == '(') /* Ouverture de parenthese, donc sous calcul (recursif) */
  3731.                                         {
  3732.                                                 if (chaine[pos - 1] == '$') fparenth++; /* Ont entre dans une fonction */
  3733.                                                 else    /* Si c'est une parenthese de priorite */
  3734.                                                 {
  3735.                                                         parenth++;
  3736.                                                         sous_pos = pos+1;       /* Enregistre le debut du sous-calcul */
  3737.  
  3738.                                                         if (ncalc > 0)
  3739.                                                         {
  3740.                                                                 if (encour || tabcalc[ncalc-1].type < 1)
  3741.                                                                 {
  3742.                                                                         erreur = "Fonction ou ouverture de parenthese a la suite d'une valeur !";
  3743.                                                                         break;
  3744.                                                                 }
  3745.                                                         }
  3746.                                                 }
  3747.                                         }
  3748.                                         else if (chaine[pos] == ')')    /* Fermeture de parenthese alors qu'aucune n'est ouverte */
  3749.                                         {
  3750.                                                 parenth--;      /* afin que la valeur soit negatif */
  3751.                                                 break;    /* Quitte la boucle */
  3752.                                         }
  3753.                                         else if (chaine[pos] == '\"' || chaine[pos] == '\'')    /* Ouverture de guillemet */
  3754.                                         {
  3755.                                                 if (encour)     /* Si ont est deja en train de recuperer une valeur */
  3756.                                                 {
  3757.                                                         erreur = "Probleme lors de l'ouverture d'un guillemet !";
  3758.                                                         break;
  3759.                                                 }
  3760.                                                 guil = chaine[pos];
  3761.                                                 encour = TRUE;
  3762.                                                 debut = pos+1/* Enregistre la position de depart */
  3763.                                         }
  3764.                                     else
  3765.                                         {
  3766.                                                 signe = 0;
  3767.                                                 fin = pos;
  3768.                                                 if (chaine[pos] == '+' || chaine[pos] == '-')
  3769.                                                 {
  3770.                                                         if (ncalc > 0)
  3771.                                                         {
  3772.                                                                 if (tabcalc[ncalc-1].type > 0 && !encour) signe++;
  3773.                                                         }
  3774.                                                         else if (!encour) signe++;
  3775.  
  3776.                                                         if (signe < 1)
  3777.                                                         {
  3778.                                                                 if (chaine[pos] == '+') signe = 1;
  3779.                                                                 else signe = 2;
  3780.                                                         }
  3781.                                                         else
  3782.                                                         {
  3783.                                                                 fin = -1;
  3784.                                                                 debut = pos;
  3785.                                                                 encour = TRUE/* Prend ce symbole comme faisant partis d'une valeur */
  3786.                                                                 signe = 0;
  3787.                                                         }
  3788.                                                 }
  3789.                                                 else if (chaine[pos] == '^') signe = 4;
  3790.                                                 else if (chaine[pos] == '/') signe = 15;
  3791.                                                 else if (chaine[pos] == '*') signe = 14;
  3792.                                                 else if (chaine[pos] == '<' || chaine[pos] == '>')
  3793.                                                 {
  3794.                                                         if (chaine[pos] == '<') signe = 5;
  3795.                                                         else signe = 7;
  3796.  
  3797.                                                         if (chaine[pos+1] == '=')
  3798.                                                         {
  3799.                                                                 signe++;
  3800.                                                                 pos++;
  3801.                                                         }
  3802.                                                         else if (chaine[pos+1] == '>')
  3803.                                                         {
  3804.                                                                 if (signe == 5) signe = 10;
  3805.                                                                 else signe = 17;
  3806.                                                                 pos++;
  3807.                                                         }
  3808.                                                         else if (signe == 5 && chaine[pos+1] == '<')
  3809.                                                         {
  3810.                                                                 signe = 16;
  3811.                                                                 pos++;
  3812.                                                         }
  3813.                                                 }
  3814.                                                 else if (chaine[pos] == '=')
  3815.                                                 {
  3816.                                                         signe = 9;
  3817.                                                         if (chaine[pos+1] == '=') pos++;
  3818.                                                 }
  3819.                                                 else if (chaine[pos] == '!')
  3820.                                                 {
  3821.                                                         if (chaine[pos+1] == '=')
  3822.                                                         {
  3823.                                                                 signe = 10;
  3824.                                                                 pos++;
  3825.                                                         }
  3826.                                                         else
  3827.                                                         {
  3828.                                                                 if (ncalc > 0)
  3829.                                                                 {
  3830.                                                                         if (encour || tabcalc[ncalc-1].type < 1)
  3831.                                                                         {
  3832.                                                                                 erreur = "Negation a la suite d'une valeur !";
  3833.                                                                                 break;
  3834.                                                                         }
  3835.                                                                 }
  3836.                                                                 signe = 19;
  3837.                                                         }
  3838.                                                 }
  3839.                                                 else if (chaine[pos] == '|')
  3840.                                                 {
  3841.                                                         if (chaine[pos+1] == '|')
  3842.                                                         {
  3843.                                                                 signe = 11;
  3844.                                                                 pos++;
  3845.                                                         }
  3846.                                                         else signe = 3;
  3847.                                                 }
  3848.                                                 else if (chaine[pos] == '&')
  3849.                                                 {
  3850.                                                         if (chaine[pos+1] == '&')
  3851.                                                         {
  3852.                                                                 signe = 12;
  3853.                                                                 pos++;
  3854.                                                         }
  3855.                                                         else signe = 13;
  3856.                                                 }
  3857.                                                 else if (chaine[pos] == '%') signe = 18;
  3858.                                                 else if (chaine[pos] > 32 && chaine[pos] != 127)        /* Si c'est un caractere valide */
  3859.                                                 {
  3860.                                                         fin = -1;
  3861.                                                         if (!encour)
  3862.                                                         {
  3863.                                                                 encour = TRUE;
  3864.                                                                 debut = pos;    /* Enregistre la position de depart */
  3865.                                                         }
  3866.                                                 }
  3867.                                                 else if (chaine[pos] == '\0')
  3868.                                                 {
  3869.                                                         signe = 100;
  3870.                                                         /* pos--; */
  3871.                                                 }
  3872.                                        
  3873.                                                 if (fin >= 0 && encour) /* Si un mot est a recuperer */
  3874.                                                 {
  3875.                                                         if (fin - debut == 1 && (chaine[debut] == '-' || chaine[debut] == '+'))
  3876.                                                         {
  3877.                                                                 erreur = "2 symbole se suivent et le deuxieme et trop eloigne d'une valeur pour en faire partie !";
  3878.                                                                 break;
  3879.                                                         }
  3880.  
  3881.                                                         tabcalc[ncalc].chaine = interp(conf, ap_pstrndup(conf->pool_tag, &chaine[debut], fin - debut));
  3882.                                                         if (isnum(tabcalc[ncalc].chaine))       /* Si c'est un type numerique */
  3883.                                                         {
  3884.                                                                 if ((ptr = strchr(tabcalc[ncalc].chaine, ',')) != NULL) ptr[0] = '.';   /* Remplacer la virgule par un point pour que atof() convertisse correctement */
  3885.                                                                 tabcalc[ncalc].valeur = atof(tabcalc[ncalc].chaine);
  3886.                                                                 if (ptr != NULL) ptr[0] = ','/* Remettre la virgule */
  3887.                                                                 tabcalc[ncalc].type = -1;
  3888.                                                         }
  3889.                                                         else tabcalc[ncalc].type = 0;   /* Si c'est un type chaine */
  3890. TRAITE_CHAINE:
  3891.                                                         if (tabcalc[ncalc].type < 0)    /* Type numerique */
  3892.                                                         {
  3893.                                                                 if (ncalc > 0)
  3894.                                                                 {
  3895.                                                                         if (tabcalc[ncalc-1].type < 1)
  3896.                                                                         {
  3897.                                                                                 erreur = "Error: 2 valeurs se suivent !";
  3898.                                                                                 break;
  3899.                                                                         }
  3900.                                                                         else if (tabcalc[ncalc-1].type == 19)   /* Traitement de la negation */
  3901.                                                                         {
  3902.                                                                                 tabcalc[--ncalc].type = -2;
  3903.                                                                                 if (tabcalc[ncalc+1].valeur) tabcalc[ncalc].valeur = FALSE;
  3904.                                                                                 else tabcalc[ncalc].valeur = TRUE;
  3905.                                                                         }
  3906.                                                                 }
  3907. /*
  3908. ap_rprintf(conf->r," <FONT SIZE=2>[<B>%lf</B>]</FONT>", tabcalc[ncalc].valeur);
  3909. */
  3910.                                                         }
  3911.                                                         else if (tabcalc[ncalc].type == 0)      /* type chaine */
  3912.                                                         {
  3913. /*
  3914. ap_rprintf(conf->r," <FONT SIZE=2>[<B>\"%s\"</B>]</FONT>", tabcalc[ncalc].chaine);
  3915. */
  3916.                                                                 if (ncalc > 0)
  3917.                                                                 {
  3918.                                                                         if (tabcalc[ncalc-1].type < 1)
  3919.                                                                         {
  3920.                                                                                 erreur = "Error: 2 valeurs se suivent !";
  3921.                                                                                 break;
  3922.                                                                         }
  3923.                                                                         else if(tabcalc[ncalc-1].type == 19) /* Traitement de la negation */
  3924.                                                                         {
  3925.                                                                                 erreur = "Negation sur une chaine interdite";
  3926.                                                                                 break;
  3927.                                                                         }
  3928.                                                                 }
  3929.                                                         }
  3930.  
  3931.                                                         /* --- Traitement du '/', '*', '&', '<<', '>>' et '%' --- */
  3932.                                                         if (ncalc > 1)
  3933.                                                         {
  3934.                                                                 if (tabcalc[ncalc-1].type > 12 && tabcalc[ncalc-1].type < 19)
  3935.                                                                 {
  3936.                                                                         if (tabcalc[ncalc-2].type > -1 || tabcalc[ncalc].type > -1)
  3937.                                                                         {
  3938.                                                                                 erreur = "operation impossible sur une chaine !";
  3939.                                                                                 break;
  3940.                                                                         }
  3941.                                                                         else
  3942.                                                                         {
  3943.                                                                                 tempo = tabcalc[ncalc-2].valeur;
  3944. /*
  3945. ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[A:<B>%lf;%lf=", tempo, tabcalc[ncalc].valeur);
  3946. */
  3947.                                                                                 switch(tabcalc[ncalc-1].type)
  3948.                                                                                 {
  3949.                                                                                 case 13: tabcalc[ncalc-2].valeur = (double)((long int)tempo & (long int)tabcalc[ncalc].valeur);
  3950.                                                                                         break;
  3951.                                                                                 case 14: tabcalc[ncalc-2].valeur = tempo * tabcalc[ncalc].valeur;
  3952.                                                                                         break;
  3953.                                                                                 case 15: if (tabcalc[ncalc].valeur == 0)
  3954.                                                                                         {
  3955.                                                                                                 erreur = "Division par 0 interdite !";
  3956.                                                                                         }
  3957.                                                                                         else tabcalc[ncalc-2].valeur = tempo / tabcalc[ncalc].valeur;
  3958.                                                                                         break;
  3959.                                                                                 case 16: tabcalc[ncalc-2].valeur = (double)((long int)tempo << (long int)tabcalc[ncalc].valeur);
  3960.                                                                                         break;
  3961.                                                                                 case 17: tabcalc[ncalc-2].valeur = (double)((long int)tempo >> (long int)tabcalc[ncalc].valeur);
  3962.                                                                                         break;
  3963.                                                                                 case 18: tabcalc[ncalc-2].valeur = fmod(tempo, tabcalc[ncalc].valeur);
  3964.                                                                                         break;
  3965.                                                                                 default: break;
  3966.                                                                                 }
  3967.                                                                                 if (erreur != NULL) break;
  3968.                                                                                 tabcalc[ncalc-2].type = -2;     /* Valeur numerique comme resultat obligatoirement */
  3969. /*
  3970. ap_rprintf(conf->r,"%lf</B>]</FONT> ", tabcalc[ncalc-2].valeur);
  3971. */
  3972.                                                                                 ncalc -= 2;
  3973.                                                                         }
  3974.                                                                 }
  3975.                                                         }
  3976.                                                         ncalc++;
  3977.                                                         encour = FALSE;
  3978.                                                         fin = -1;
  3979.                                                 }
  3980.  
  3981.                                                 if (signe > 0)  /* Si un signe est a recuperer */
  3982.                                                 {
  3983.                                                         tabcalc[ncalc].type = signe;
  3984. /*
  3985. conf->temp = "";
  3986. switch(signe)
  3987. {
  3988. case 1: conf->temp = "+"; break;
  3989. case 2: conf->temp = "-"; break;
  3990. case 3: conf->temp = "|"; break;
  3991. case 4: conf->temp = "^"; break;
  3992. case 5: conf->temp = "<"; break;
  3993. case 6: conf->temp = "<="; break;
  3994. case 7: conf->temp = ">"; break;
  3995. case 8: conf->temp = ">="; break;
  3996. case 9: conf->temp = "=="; break;
  3997. case 10: conf->temp = "!="; break;
  3998. case 11: conf->temp = "||"; break;
  3999. case 12: conf->temp = "&&"; break;
  4000. case 13: conf->temp = "&"; break;
  4001. case 14: conf->temp = "*"; break;
  4002. case 15: conf->temp = "/"; break;
  4003. case 16: conf->temp = "<<"; break;
  4004. case 17: conf->temp = ">>"; break;
  4005. case 18: conf->temp = "%"; break;
  4006. case 19: conf->temp = "!"; break;
  4007. case 20: conf->temp = "~"; break;
  4008. case 100: conf->temp = "FIN"; break;
  4009. default: conf->temp = "INCONNU!"; break;
  4010. }
  4011. ap_rprintf(conf->r, " <FONT SIZE=2>[<B>%s</B>]</FONT> ", conf->temp);
  4012. */
  4013.  
  4014.                                                         if (ncalc < 1 && signe != 100)
  4015.                                                         {
  4016.                                                                 if (signe != 1 && signe != 2 && signe != 19)
  4017.                                                                 {
  4018.                                                                         erreur = "symbole interdit en debut de calcul ou de parenthese !";
  4019.                                                                         break;
  4020.                                                                 }
  4021.                                                         }
  4022.                                                         else if (signe != 100)
  4023.                                                         {
  4024.                                                                 if ((tabcalc[ncalc-1].type > 0 && tabcalc[ncalc].type != 19) || (tabcalc[ncalc-1].type == 19 && tabcalc[ncalc].type == 19))
  4025.                                                                 {
  4026.                                                                         if (tabcalc[ncalc].type == 100) erreur = "1 symbole se trouve seul a la fin";
  4027.                                                                         else erreur = "2 symboles se suivent !";
  4028.                                                                         break;
  4029.                                                                 }
  4030.                                                         }
  4031.  
  4032.                                                         /* --- Traitement du '+', '-', '|' et '^' --- */
  4033.                                                         if (ncalc > 2 && ((signe > 0 && signe < 13) || signe == 100))
  4034.                                                         {
  4035.                                                                 if (tabcalc[ncalc-2].type > 0 && tabcalc[ncalc-2].type < 5)
  4036.                                                                 {
  4037.                                                                         if ((tabcalc[ncalc-3].type > -1 || tabcalc[ncalc-1].type > -1) && tabcalc[ncalc-2].type != 1)
  4038.                                                                         {
  4039.                                                                                 erreur = "operation impossible sur une chaine !";
  4040.                                                                                 break;
  4041.                                                                         }
  4042.                                                                         else
  4043.                                                                         {
  4044.                                                                                 tempo = tabcalc[ncalc-3].valeur;
  4045. /*
  4046. if (tabcalc[ncalc-3].type == 0 && tabcalc[ncalc-1].type == 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[B:<B>\"%s\";\"%s\"=", tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].chaine);
  4047. else if (tabcalc[ncalc-3].type != 0 && tabcalc[ncalc-1].type == 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[B:<B>%lf;\"%s\"=", tempo, tabcalc[ncalc-1].chaine);
  4048. else if (tabcalc[ncalc-3].type == 0 && tabcalc[ncalc-1].type != 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[B:<B>\"%s\";%s=", tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].valeur);
  4049. else ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[B:<B>%lf;%lf=", tempo, tabcalc[ncalc-1].valeur);
  4050. */
  4051.                                                                                 switch(tabcalc[ncalc-2].type)
  4052.                                                                                 {
  4053.                                                                                 case 1: if (tabcalc[ncalc-3].type > -1 || tabcalc[ncalc-1].type > -1)   /* addition de type chaine */
  4054.                                                                                         {
  4055.                                                                                                 if (tabcalc[ncalc-3].type < -1 || tabcalc[ncalc-1].type < -1)
  4056.                                                                                                 {
  4057.                                                                                                         erreur = "Operation impossible entre une chaine et une valeur numerique !";
  4058.                                                                                                 }
  4059.                                                                                                 else
  4060.                                                                                                 {
  4061.                                                                                                         tabcalc[ncalc-3].type = 0;      /* Resultat de type chaine */
  4062.                                                                                                         tabcalc[ncalc-3].chaine = ap_pstrcat(conf->pool_tag, tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].chaine, NULL);   /* Additionne les deux chaines */
  4063.                                                                                                 }
  4064.                                                                                         }
  4065.                                                                                         else
  4066.                                                                                         {
  4067.                                                                                                 tabcalc[ncalc-3].type = -2;
  4068.                                                                                                 tabcalc[ncalc-3].valeur = tempo + tabcalc[ncalc-1].valeur;
  4069.                                                                                         }
  4070.                                                                                         break;
  4071.                                                                                 case 2: tabcalc[ncalc-3].valeur = tempo - tabcalc[ncalc-1].valeur;
  4072.                                                                                         break;
  4073.                                                                                 case 3: tabcalc[ncalc-3].valeur = (double)((long int)tempo | (long int)tabcalc[ncalc-1].valeur);
  4074.                                                                                         break;
  4075.                                                                                 case 4: tabcalc[ncalc-3].valeur = (double)((long int)tempo ^ (long int)tabcalc[ncalc-1].valeur);
  4076.                                                                                         break;
  4077.                                                                                 default:
  4078.                                                                                         break;
  4079.                                                                                 }
  4080.                                                                                 if (erreur != NULL) break;
  4081.                                                                                 if (tabcalc[ncalc-2].type != 1) tabcalc[ncalc-3].type = -2;     /* Valeur numerique comme resultat sauf pour le plus */
  4082. /*
  4083. if (tabcalc[ncalc-3].type < 0) ap_rprintf(conf->r,"%lf</B>]</FONT> ", tabcalc[ncalc-3].valeur);
  4084. else ap_rprintf(conf->r,"%s</B>]</FONT> ", tabcalc[ncalc-3].chaine);
  4085. */
  4086.                                                                                 tabcalc[ncalc-2].type = tabcalc[ncalc].type;
  4087.                                                                                 ncalc -= 2;
  4088.                                                                         }
  4089.                                                                 }
  4090.                                                         }
  4091.  
  4092.                                                         if (ncalc > 2 && signe > 4 && signe < 11)
  4093.                                                         {
  4094.                                                                 if (tabcalc[ncalc-2].type > 4 && tabcalc[ncalc-2].type < 11)
  4095.                                                                 {
  4096.                                                                         erreur = "2 signe logique ne peuvent se suivrent !";
  4097.                                                                         break;
  4098.                                                                 }
  4099.                                                         }
  4100.  
  4101.                                                         if (ncalc > 2 && (signe == 11 || signe == 12 || signe == 100))
  4102.                                                         {
  4103.                                                                 if ((signe == 11 || signe == 12 || signe == 100) && ((tabcalc[ncalc-2].type > 4 && tabcalc[ncalc-2].type < 11) || tabcalc[ncalc-2].type == 12))
  4104.                                                                 {
  4105.                                                                         if ((tabcalc[ncalc-3].type > -1 || tabcalc[ncalc-1].type > -1) && tabcalc[ncalc-2].type > 4 && tabcalc[ncalc-2].type < 9)
  4106.                                                                         {
  4107.                                                                                 erreur = "operation impossible sur une chaine !";
  4108.                                                                         }
  4109.                                                                         else
  4110.                                                                         {
  4111.                                                                                 tempo = tabcalc[ncalc-3].valeur;
  4112.                                                                                 tabcalc[ncalc-3].valeur = FALSE;        /* resultat du test logique FAUX par defaut */
  4113.  
  4114. /*
  4115. if (tabcalc[ncalc-3].type == 0 && tabcalc[ncalc-1].type == 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[C:<B>\"%s\";\"%s\"=", tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].chaine);
  4116. else if (tabcalc[ncalc-3].type != 0 && tabcalc[ncalc-1].type == 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[C:<B>%lf;\"%s\"=", tempo, tabcalc[ncalc-1].chaine);
  4117. else if (tabcalc[ncalc-3].type == 0 && tabcalc[ncalc-1].type != 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[C:<B>\"%s\";%s=", tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].valeur);
  4118. else ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[C:<B>%lf;%lf=", tempo, tabcalc[ncalc-1].valeur);
  4119. */
  4120.                                                                                 switch(tabcalc[ncalc-2].type)
  4121.                                                                                 {
  4122.                                                                                 case 5: if (tempo < tabcalc[ncalc-1].valeur) tabcalc[ncalc-3].valeur = TRUE;
  4123.                                                                                         break;
  4124.                                                                                 case 6: if (tempo <= tabcalc[ncalc-1].valeur) tabcalc[ncalc-3].valeur = TRUE;
  4125.                                                                                         break;
  4126.                                                                                 case 7: if (tempo > tabcalc[ncalc-1].valeur) tabcalc[ncalc-3].valeur = TRUE;
  4127.                                                                                         break;
  4128.                                                                                 case 8: if (tempo >= tabcalc[ncalc-1].valeur) tabcalc[ncalc-3].valeur = TRUE;
  4129.                                                                                         break;
  4130.                                                                                 case 9: if (tabcalc[ncalc-3].type > -1 || tabcalc[ncalc-1].type > -1)   /* comparaison de type chaine */
  4131.                                                                                         {
  4132.                                                                                                 if (tabcalc[ncalc-3].type < -1 || tabcalc[ncalc-1].type < -1)
  4133.                                                                                                 {
  4134.                                                                                                         erreur = "Operation impossible entre une chaine et une valeur numerique !";
  4135.                                                                                                 }
  4136.                                                                                                 else if (!strcmp(tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].chaine)) tabcalc[ncalc-3].valeur = TRUE;
  4137.                                                                                         }
  4138.                                                                                         else if (tempo == tabcalc[ncalc-1].valeur) tabcalc[ncalc-3].valeur = TRUE;
  4139.                                                                                         break;
  4140.                                                                                 case 10: if (tabcalc[ncalc-3].type > -1 || tabcalc[ncalc-1].type > -1)  /* comparaison de type chaine */
  4141.                                                                                         {
  4142.                                                                                                 if (tabcalc[ncalc-3].type < -1 || tabcalc[ncalc-1].type < -1)
  4143.                                                                                                 {
  4144.                                                                                                         erreur = "Operation impossible entre une chaine et une valeur numerique !";
  4145.                                                                                                 }
  4146.                                                                                                 else if (strcmp(tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].chaine)) tabcalc[ncalc-3].valeur = TRUE;
  4147.                                                                                         }
  4148.                                                                                         else if (tempo != tabcalc[ncalc-1].valeur) tabcalc[ncalc-3].valeur = TRUE;
  4149.                                                                                         break;
  4150.                                                                                 case 12: if (tabcalc[ncalc-3].type == 0) tempo = ifvide(tabcalc[ncalc-3].chaine);
  4151.                                                                                         if (tabcalc[ncalc-1].type == 0) tabcalc[ncalc-1].valeur = ifvide(tabcalc[ncalc-1].chaine);
  4152.  
  4153.                                                                                         if (tabcalc[ncalc-2].type == 11 && (tempo || tabcalc[ncalc-1].valeur)) tabcalc[ncalc-3].valeur = TRUE;
  4154.                                                                                         else if (tabcalc[ncalc-2].type == 12 && (tempo && tabcalc[ncalc-1].valeur)) tabcalc[ncalc-3].valeur = TRUE;
  4155.                                                                                         break;
  4156.                                                                                 default:
  4157.                                                                                         break;
  4158.                                                                                 }
  4159.                                                                                 if (erreur != NULL) break;
  4160.                                                                                 tabcalc[ncalc-3].type = -2;     /* Valeur numerique comme resultat obligatoirement */
  4161. /*
  4162. ap_rprintf(conf->r,"%lf</B>]</FONT> ", tabcalc[ncalc-3].valeur);
  4163. */
  4164.                                                                                 tabcalc[ncalc-2].type = tabcalc[ncalc].type;
  4165.                                                                                 ncalc -= 2;
  4166.                                                                         }
  4167.                                                                 }
  4168.                                                         }
  4169.  
  4170. DERNIERE_PASSE:
  4171.                                                         if (ncalc > 2 && (signe == 11 || signe == 100))
  4172.                                                         {
  4173.                                                                 if (tabcalc[ncalc-2].type > 10 && tabcalc[ncalc-2].type < 13)
  4174.                                                                 {
  4175.                                                                         tempo = tabcalc[ncalc-3].valeur;
  4176.                                                                         tabcalc[ncalc-3].valeur = FALSE;        /* resultat du test logique FAUX par defaut */
  4177. /*
  4178. if (tabcalc[ncalc-3].type == 0 && tabcalc[ncalc-1].type == 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[D:<B>\"%s\";\"%s\"=", tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].chaine);
  4179. else if (tabcalc[ncalc-3].type != 0 && tabcalc[ncalc-1].type == 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[D:<B>%lf;\"%s\"=", tempo, tabcalc[ncalc-1].chaine);
  4180. else if (tabcalc[ncalc-3].type == 0 && tabcalc[ncalc-1].type != 0) ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[D:<B>\"%s\";%s=", tabcalc[ncalc-3].chaine, tabcalc[ncalc-1].valeur);
  4181. else ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#FF0000>[D:<B>%lf;%lf=", tempo, tabcalc[ncalc-1].valeur);
  4182. */
  4183.                                                                         if (tabcalc[ncalc-3].type == 0) tempo = ifvide(tabcalc[ncalc-3].chaine);
  4184.                                                                         if (tabcalc[ncalc-1].type == 0) tabcalc[ncalc-1].valeur = ifvide(tabcalc[ncalc-1].chaine);
  4185.  
  4186.                                                                         if (tabcalc[ncalc-2].type == 11 && (tempo || tabcalc[ncalc-1].valeur)) tabcalc[ncalc-3].valeur = TRUE;
  4187.                                                                         else if (tabcalc[ncalc-2].type == 12 && (tempo && tabcalc[ncalc-1].valeur)) tabcalc[ncalc-3].valeur = TRUE;
  4188.  
  4189.                                                                         tabcalc[ncalc-3].type = -2;     /* Valeur numerique comme resultat obligatoirement */
  4190. /*
  4191. ap_rprintf(conf->r,"%lf</B>]</FONT> ", tabcalc[ncalc-3].valeur);
  4192. */
  4193.                                                                         tabcalc[ncalc-2].type = tabcalc[ncalc].type;
  4194.                                                                         ncalc -= 2;
  4195.                                                                 }
  4196.                                                         }
  4197.  
  4198.                                                         if (ncalc > 2 && signe == 100)
  4199.                                                         {
  4200.                                                                 if (tabcalc[ncalc-2].type == 11 || tabcalc[ncalc-2].type == 12) goto DERNIERE_PASSE;
  4201.                                                         }
  4202.  
  4203.                                                         ncalc++;
  4204. /*
  4205. ap_rprintf(conf->r," <FONT SIZE=1 COLOR=#C0C0C0>{%d}</FONT> ", ncalc);
  4206. */
  4207.                                                 }
  4208.                                         }
  4209.                                 }
  4210.                         }
  4211.                         else    /* Si les guillemets sont deja ouvert */
  4212.                         {
  4213.                                 if (chaine[pos] == guil)        /* Si les guillemets se ferme */
  4214.                                 {
  4215.                                         guil = '\0';
  4216.                                         tabcalc[ncalc].type = 0;
  4217.                                         tabcalc[ncalc].chaine = interp(conf, ap_pstrndup(conf->pool_tag, &chaine[debut], pos - debut));
  4218.                                         signe = 0;
  4219.                                         goto TRAITE_CHAINE;
  4220.                                 }
  4221.                         }
  4222.                 }
  4223.         }
  4224.         while(chaine[pos++] != '\0');
  4225.  
  4226.         if (guil != '\0')
  4227.         {
  4228.                 erreur = "Des guillemets n'ont pas ete referme !";
  4229.         }
  4230.         else if (parenth != 0)
  4231.         {
  4232.                 erreur = "Erreur de parenthese !";      /* Erreur de parenthesage */
  4233.         }
  4234.  
  4235.         if (erreur != NULL)     /* Genere une erreur */
  4236.         {
  4237.                 return(ap_pstrcat(conf->pool_tag, "Error: ", erreur, NULL));
  4238.         }
  4239.  
  4240. /*
  4241. ap_rprintf(conf->r, "<BR><TT><B><FONT COLOR=#0000FF>");
  4242. for(pos=0; pos < ncalc; pos++)
  4243. {
  4244.         if (tabcalc[pos].type < 0) ap_rprintf(conf->r, " [%lf] ", tabcalc[pos].valeur);
  4245.         else if (tabcalc[pos].type == 0) ap_rprintf(conf->r, " [%s] ", tabcalc[pos].chaine);
  4246.         else
  4247.         {
  4248.                 conf->temp = "";
  4249.                 switch(tabcalc[pos].type)
  4250.                 {
  4251.                 case 1: conf->temp = "+"; break;
  4252.                 case 2: conf->temp = "-"; break;
  4253.                 case 3: conf->temp = "|"; break;
  4254.                 case 4: conf->temp = "^"; break;
  4255.                 case 5: conf->temp = "<"; break;
  4256.                 case 6: conf->temp = "<="; break;
  4257.                 case 7: conf->temp = ">"; break;
  4258.                 case 8: conf->temp = ">="; break;
  4259.                 case 9: conf->temp = "=="; break;
  4260.                 case 10: conf->temp = "!="; break;
  4261.                 case 11: conf->temp = "||"; break;
  4262.                 case 12: conf->temp = "&&"; break;
  4263.                 case 13: conf->temp = "&"; break;
  4264.                 case 14: conf->temp = "*"; break;
  4265.                 case 15: conf->temp = "/"; break;
  4266.                 case 16: conf->temp = "<<"; break;
  4267.                 case 17: conf->temp = ">>"; break;
  4268.                 case 18: conf->temp = "%"; break;
  4269.                 case 19: conf->temp = "!"; break;
  4270.                 case 20: conf->temp = "~"; break;
  4271.                 case 100: conf->temp = "FIN"; break;
  4272.                 default: break;
  4273.                 }
  4274.                 ap_rprintf(conf->r, " [%s] ", conf->temp);
  4275.         }
  4276. }
  4277. ap_rprintf(conf->r, "</FONT></B></TT>");
  4278. */
  4279.  
  4280.         if (ncalc < 2)
  4281.         {
  4282.                 tabcalc[0].type = 0;
  4283.                 tabcalc[0].chaine = ""/* Renvoi une chaine vide */
  4284.         }
  4285.  
  4286.         if (tabcalc[0].type < 0)        /* Valeur Numerique */
  4287.         {
  4288. /*
  4289. ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#00C000>[<B>%lf</B>]</FONT><BR> ", tabcalc[0].valeur);
  4290. */
  4291.                 conf->calcul = tabcalc[0].valeur;
  4292.                 return("-VaL*");
  4293.         }
  4294.         else if (tabcalc[0].type == 0)  /* Retourne une chaine */
  4295.         {
  4296. /*
  4297. ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#00C000>[<B>\"%s\"</B>]</FONT><BR> ", tabcalc[0].chaine);
  4298. */
  4299.                         return(tabcalc[0].chaine);
  4300.         }
  4301.         else    /* ERREUR */
  4302.         {
  4303. /*
  4304. ap_rprintf(conf->r," <FONT SIZE=2 COLOR=#00C000>[<B>ERROR!</B>]</FONT><BR> ");
  4305. */
  4306.                 return("Error: il ne reste pas une valeur !");
  4307.         }
  4308. }
  4309.  
  4310. /*--------------------------------------------------------------------------*/
  4311. /* Effectue un calcul mathematique et renvoi le resultat en double          */
  4312. /* En cas d'erreur, renvoi 0                                                */
  4313. /*--------------------------------------------------------------------------*/
  4314. static double calc(adml_cfg *conf, const char *chaine)
  4315. {
  4316.         char *reponse;
  4317.  
  4318.         if ((reponse = calcul(conf, chaine)) == NULL)
  4319.         {
  4320.                 if (if_sortie) imprime(conf, "%s", "Erreur: fonction vide !");
  4321.                 return(0);
  4322.         }
  4323.  
  4324.         if (!strncmp(reponse, "Error: ", 7))    /* Erreur */
  4325.         {
  4326.                 imprime(conf, "%s", &reponse[7]);
  4327.         }
  4328.         else if (!strcmp(reponse, "-VaL*")) return(conf->calcul);       /* Valeur numerique */
  4329.  
  4330.         imprime(conf, "%s", "Erreur: le resultat du calcul est une chaine : '%s'", &reponse[7]);
  4331.         return(0);      /* Erreur */
  4332. }
  4333.  
  4334. /*--------------------------------------------------------------------------*/
  4335. /* Effectue le test logique passer dans chaine et renvoie TRUE ou FALSE     */
  4336. /*--------------------------------------------------------------------------*/
  4337. static int testlog(adml_cfg *conf, const char *chaine)
  4338. {
  4339.         char *reponse;
  4340.  
  4341.         if ((reponse = calcul(conf, chaine)) == NULL) return(FALSE);
  4342.  
  4343.         if (!strncmp(reponse, "Error: ", 7))    /* Erreur */
  4344.         {
  4345.                 if (if_sortie) imprime(conf, "%s", &reponse[7]);
  4346.         }
  4347.         else if (!strcmp(reponse, "-VaL*"))     /* Valeur numerique */
  4348.         {
  4349.                 if (conf->calcul) return(TRUE);
  4350.         }
  4351.         else if (!ifvide(reponse)) return(TRUE);        /* Chaine */
  4352.  
  4353.         return(FALSE)/* FAUX */
  4354. }
  4355.  
  4356. /*--------------------------------------------------------------------------*/
  4357. /* Analyse une chaine                                                       */
  4358. /*--------------------------------------------------------------------------*/
  4359. static char *interp(adml_cfg *conf, const char *chaine)
  4360. {
  4361. #define N_REC 20
  4362. #define MEM_SUPP 128
  4363.         int pos, pos_result, taille, taille_result, nrec, parenth, virgule;
  4364.         char *result, *temp, *temp1;
  4365.         int d1, d2;
  4366.  
  4367.         if (chaine == NULL) return(NULL);
  4368.  
  4369.         taille = taille_result = strlen(chaine);        /* Recupere la taille de la chaine */
  4370.         result = ap_pcalloc(conf->pool_tag, taille_result+1);   /* Alloue un peu de place */
  4371.  
  4372.         pos_result = parenth = 0;
  4373.         pos = -1;
  4374.         while(chaine[++pos] != '\0')
  4375.         {
  4376.                 if (chaine[pos] == '$' && chaine[pos+1] == '(') /* Debut de fonction */
  4377.                 {
  4378.                         pos++;
  4379.                         d1 = pos+1;     /* debut du nom de la fonction */
  4380.                         parenth = 1;
  4381.                         virgule = FALSE;
  4382.                         while(parenth > 0 && chaine[++pos] != '\0')
  4383.                         {
  4384.                                 if (chaine[pos] == ')') parenth--;
  4385.                                 else if (chaine[pos] == '(') parenth++;
  4386.  
  4387.                                 if (!virgule && parenth == 1 && chaine[pos] == ',')
  4388.                                 {
  4389.                                         d2 = pos+1;     /* debut de la valeur de la fonction */
  4390.                                         virgule = TRUE;
  4391.                                 }
  4392.                         }
  4393.  
  4394.  
  4395.                         if (!virgule) d2 = pos;
  4396.                         if (d2-d1-1 > 0) temp = ap_pstrndup(conf->pool_tag, &chaine[d1], d2-d1-1);
  4397.                         else temp = "";
  4398.                         if (pos-d2 > 0) temp1 = ap_pstrndup(conf->pool_tag, &chaine[d2], pos-d2);
  4399.                         else temp1 = "";
  4400.  
  4401.                         temp = exec_fonction(conf, temp, temp1);        /* execute la fonction */
  4402.  
  4403.                         d1 = strlen(temp);
  4404.                         d2 = taille_result + d1 + (taille - pos) + MEM_SUPP;
  4405.                         if (taille_result < d2)
  4406.                         {
  4407.                                 taille_result = d2;
  4408.                                 temp1 = result; /* Conserve le pointeur */
  4409.                                 result = ap_pcalloc(conf->pool_tag, taille_result+1);   /* Alloue une tranche de memoire supplementaire */
  4410.                                 memcpy(result, temp1, sizeof(char) * pos_result);       /* recopie la chaine */
  4411.                                 memcpy(&result[pos_result], temp, sizeof(char) * d1);   /* Ajoute le resultat de la fonction */
  4412.                                 pos_result += d1;       /* repositionne le pointeur */
  4413.                                 result[pos_result] = '\0';      /* Pour etre sur qu'il y aura une fin de chaine */
  4414.                         }
  4415.                         if (chaine[pos] == '\0') pos--; /* Fait en sorte que la boucle principale prenne en compte egalement la fin de chaine */
  4416.                 }
  4417.                 else
  4418.                 {
  4419.                         if (pos_result >= taille_result)
  4420.                         {
  4421.                                 taille_result += MEM_SUPP;
  4422.                                 temp = result;  /* Conserve le pointeur */
  4423.                                 result = ap_pcalloc(conf->pool_tag, taille_result+1);   /* Alloue une tranche de memoire supplementaire */
  4424.                                 memcpy(result, temp, sizeof(char) * pos_result);        /* recopie la chaine */
  4425.                         }
  4426.                         result[pos_result++] = chaine[pos];
  4427.                 }
  4428.         }
  4429.  
  4430.         return(result);
  4431. }
  4432.  
  4433. /*--------------------------------------------------------------------------*/
  4434. /* Interprete tag  */
  4435. /*--------------------------------------------------------------------------*/
  4436. static void interprete_tag(request_rec *r)
  4437. {
  4438.         adml_cfg *conf;
  4439.         array_header *arr, *temp_arr;
  4440.         table_entry *elts, *temp_elts;
  4441.         const char *param[10];
  4442.         char *valeur, *temp;
  4443.         int i, w, x, y, z, flag, condition;
  4444.         int num[10];
  4445.         char *error = NULL;
  4446.         FILE *f;
  4447.         char c;
  4448.         adml_cfg toto;  /* Afin de conserver une copie de la conf (voir include type=virtual|file) */
  4449.         uri_components uptr;    /* Pour stocker les composants d'une URI */
  4450.         time_t secs;
  4451.         pool *pool_temp;        /* Pool de Sauvegarde ou pour usage temporaire (attention, pensez a le supprimer apres utilisation) */
  4452.  
  4453.         conf = (adml_cfg *) ap_get_module_config(r->per_dir_config, &adml_module);      /* recupere la config */
  4454.  
  4455.         arr = ap_table_elts(conf->tag)/* Recupere le tableau de la table */
  4456.         elts = (table_entry *) arr->elts;
  4457.  
  4458.         valeur = interp(conf, elts[0].val);     /* Interpretation de la valeur du nom du TAG */
  4459.  
  4460.         error = NULL;        /* Initialisation (ne peut pas etre mis dans la declaration de error) */
  4461.         if (arr->nelts > 0)
  4462.         {
  4463.                 /*----------------------------------------------------------------*/
  4464.                 /* IF...                                                          */
  4465.                 /*----------------------------------------------------------------*/
  4466.                 /* ---------- IF ---------- */
  4467.                 if ((!strncasecmp(elts[0].key, "if", 2) || !strncasecmp(elts[0].key, "else_if", 7) || !strncasecmp(elts[0].key, "elseif", 6)) && conf->nwhile < N_WHILE)
  4468.                 {
  4469.                         if (!strncasecmp(elts[0].key, "if", 2))
  4470.                         {
  4471.                                 if (conf->ifwhile[conf->nwhile++].execute)      /* Si l'execution est autorise actuellement */
  4472.                                 {
  4473.                                         conf->ifwhile[conf->nwhile].type = 1;   /* Type IF */
  4474.                                         conf->ifwhile[conf->nwhile].sortie = conf->ifwhile[conf->nwhile-1].sortie;
  4475.                                         conf->ifwhile[conf->nwhile].execute = TRUE;     /* Par defaut */
  4476.                                 }
  4477.                                 else
  4478.                                 {
  4479.                                         conf->ifwhile[conf->nwhile].type = 2;
  4480.                                 }
  4481.                         }
  4482.  
  4483.                         condition = FALSE;      /* Faux par defaut */
  4484.  
  4485.                         if (!strncasecmp(elts[0].key, "else_if", 7) && (conf->nwhile < 1 || (conf->ifwhile[conf->nwhile].type != 1 && conf->ifwhile[conf->nwhile].type != 2)))  /* Erreur */
  4486.                         {
  4487.                                 imprime(conf, "%s", "Erreur, ce tag ELSE_IF n'est pas associe a un IF !");      /* Erreur */
  4488.                         }
  4489.                         else
  4490.                         {
  4491.                                 if (conf->ifwhile[conf->nwhile].type == 1)
  4492.                                 {
  4493.                                         /* ---------- IF ---------- */
  4494.                                         if (!strcasecmp(elts[0].key, "if") || !strcasecmp(elts[0].key, "else_if") || !strcasecmp(elts[0].key, "elseif")) condition = testlog(conf, elts[0].val);
  4495.                                         /* ---------- IF_EMPTY ---------- */
  4496.                                         else if (!strcasecmp(elts[0].key, "if_empty") || !strcasecmp(elts[0].key, "ifempty") || !strcasecmp(elts[0].key, "else_if_empty") || !strcasecmp(elts[0].key, "elseif_empty")) condition = ifvide(valeur);
  4497.                                         /* ---------- IF_DIR ---------- */
  4498.                                         else if (!strncasecmp(elts[0].key, "if_dir", 6) || !strncasecmp(elts[0].key, "else_if_dir", 11) || !strncasecmp(elts[0].key, "elseif_dir", 10))
  4499.                                         {
  4500.                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(valeur,r);
  4501.                                                 if (S_ISDIR(conf->rr->finfo.st_mode)) condition = TRUE/* Oui, c'est un fichier */
  4502.                                         }
  4503.                                         /* ---------- IF_FILE ou IFFILE ou ELSE_IF_FILE ou ELSEIF_FILE ou ELSEIFFILE ---------- */
  4504.                                         else if (!strcasecmp(elts[0].key, "if_file") || !strcasecmp(elts[0].key, "iffile") || !strcasecmp(elts[0].key, "else_if_file") || !strcasecmp(elts[0].key, "elseif_file") || !strcasecmp(elts[0].key, "elseiffile"))
  4505.                                         {
  4506.                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(valeur,r);
  4507.                                                 if (S_ISREG(conf->rr->finfo.st_mode)) condition = TRUE/* Oui, c'est un fichier */
  4508.                                         }
  4509.                                         /* ---------- IF_READ... ---------- */
  4510.                                         else if (!strncasecmp(elts[0].key, "if_read", 7) || !strncasecmp(elts[0].key, "ifread", 6) || !strncasecmp(elts[0].key, "else_if_read", 12) || !strncasecmp(elts[0].key, "elseif_read", 11))
  4511.                                         {
  4512.                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(valeur,r);
  4513.                                                 if (S_ISREG(conf->rr->finfo.st_mode))   /* Oui, c'est un fichier */
  4514.                                                 {
  4515.                                                         if (access(conf->rr->filename, R_OK) == 0) condition = TRUE;
  4516.                                                 }
  4517.                                         }
  4518.                                         /* ---------- IF_WRITE... ---------- */
  4519.                                         else if (!strncasecmp(elts[0].key, "if_write", 8) || !strncasecmp(elts[0].key, "ifwrite", 7) || !strncasecmp(elts[0].key, "else_if_write", 13) || !strncasecmp(elts[0].key, "elseif_write", 12))
  4520.                                         {
  4521.                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(valeur,r);
  4522.                                                 if (S_ISREG(conf->rr->finfo.st_mode))   /* Oui, c'est un fichier */
  4523.                                                 {
  4524.                                                         if (access(conf->rr->filename, W_OK) == 0) condition = TRUE;
  4525.                                                 }
  4526.                                         }
  4527.                                         /* ---------- IF_EXEC... ---------- */
  4528.                                         else if (!strncasecmp(elts[0].key, "if_exec", 7) || !strncasecmp(elts[0].key, "ifexec", 6) || !strncasecmp(elts[0].key, "else_if_exec", 12) || !strncasecmp(elts[0].key, "elseif_exec", 11))
  4529.                                         {
  4530.                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(valeur,r);
  4531.                                                 if (S_ISREG(conf->rr->finfo.st_mode))   /* Oui, c'est un fichier */
  4532.                                                 {
  4533.                                                         if (access(conf->rr->filename, X_OK) == 0) condition = TRUE;
  4534.                                                 }
  4535.                                         }
  4536.                                         /* ---------- IF_TPECM... ---------- */
  4537.                                         else if (!strncasecmp(elts[0].key, "if_tpecm", 8) || !strncasecmp(elts[0].key, "iftpecm", 7) || !strncasecmp(elts[0].key, "else_if_tpecm", 13) || !strncasecmp(elts[0].key, "elseif_tpecm", 12))
  4538.                                         {
  4539. #if _TPE_CM > 0  /* TPE du Credit Mutuel */
  4540.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "mac"))) == NULL) param[1] = "";
  4541.                                                 if ((param[2] = interp(conf, ap_table_get(conf->tag, "version"))) != NULL) param[2] = "";
  4542.                                                 if ((param[3] = interp(conf, ap_table_get(conf->tag, "tpe"))) != NULL) param[3] = "";
  4543.                                                 if ((param[4] = interp(conf, ap_table_get(conf->tag, "date"))) != NULL) param[4] = "";
  4544.                                                 if ((param[5] = interp(conf, ap_table_get(conf->tag, "amount"))) != NULL) param[5] = "";
  4545.                                                 if ((param[6] = interp(conf, ap_table_get(conf->tag, "ref"))) != NULL) param[6] = "";
  4546.                                                 if ((param[7] = interp(conf, ap_table_get(conf->tag, "text"))) != NULL) param[7] = "";
  4547.                                                 if ((param[8] = interp(conf, ap_table_get(conf->tag, "codereturn"))) != NULL) param[8] = "";
  4548.  
  4549.                                                 if (TestMAC(param[1], param[2], param[3], param[4], param[5], param[6], param[7], param[8])) condition = TRUE/* OK, le code MAC est correct */
  4550. #else
  4551.         /* WARNING : Tag non implementer !!! */
  4552. #endif
  4553.                                         }
  4554.                                         /* ---------- IF_HEADERAUTH... ---------- */
  4555.                                         else if (!strncasecmp(elts[0].key, "if_headerauth", 13) || !strncasecmp(elts[0].key, "ifheaderauth", 12) || !strncasecmp(elts[0].key, "else_if_headerauth", 18) || !strncasecmp(elts[0].key, "elseif_headerauth", 17))
  4556.                                         {
  4557.                                                 if (conf->auth_user)    /* OUI, il y a un element d'entete pour l'authentification de recupere */
  4558.                                                 {
  4559.                                                         flag = TRUE;
  4560.                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag, "user"))) != NULL)
  4561.                                                         {
  4562.                                                                 if (strcmp(param[1], conf->auth_user)) flag = FALSE;    /* Nom d'utilisateur incorrect */
  4563.                                                         }
  4564.  
  4565.                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag, "password"))) != NULL)
  4566.                                                         {
  4567.                                                                 if (strcmp(param[1], conf->auth_passwd)) flag = FALSE/* Mot de passe incorrect */
  4568.                                                         }
  4569.  
  4570.                                                         if (flag) condition = TRUE;
  4571.                                                 }
  4572.                                         }
  4573.                                         /* ---------- Ce n'est pas une commande IF connue ---------- */
  4574.                                         else condition = -1;
  4575.  
  4576.                                         if (condition < 0)      /* Si c'est un TAG inconnu */
  4577.                                         {
  4578.                                                 if (!strncasecmp(elts[0].key, "if", 2)) conf->nwhile--;
  4579.                                         }
  4580.                                         else if (!condition)
  4581.                                         {
  4582.                                                 conf->ifwhile[conf->nwhile].sortie = FALSE;
  4583.                                                 conf->ifwhile[conf->nwhile].execute = FALSE;    /* FAUX */
  4584.                                         }
  4585.                                         else    /* VRAIE */
  4586.                                         {
  4587.                                                 conf->ifwhile[conf->nwhile].type = 2;
  4588.                                                 conf->ifwhile[conf->nwhile].sortie = conf->ifwhile[conf->nwhile-1].sortie;
  4589.                                                 conf->ifwhile[conf->nwhile].execute = conf->ifwhile[conf->nwhile-1].execute;
  4590.                                         }
  4591.                                 }
  4592.                                 else
  4593.                                 {
  4594.                                         conf->ifwhile[conf->nwhile].sortie = FALSE;
  4595.                                         conf->ifwhile[conf->nwhile].execute = FALSE;    /* Coupe la sortie et l'execution */
  4596.                                 }
  4597.                         }
  4598.                 }
  4599.                 /*----------------------------------------------------------------*/
  4600.                 /* ELSE                                                           */
  4601.                 /*----------------------------------------------------------------*/
  4602.                 else if (!strcasecmp(elts[0].key,"else") && conf->nwhile < N_WHILE)
  4603.                 {
  4604.                         if (conf->nwhile > 0 && conf->ifwhile[conf->nwhile].type == 1 || conf->ifwhile[conf->nwhile].type == 2)
  4605.                         {
  4606.                                 if (conf->ifwhile[conf->nwhile-1].execute)      /* Si l'execution est autorise sur le niveau precedent */
  4607.                                 {
  4608.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"if"))) != NULL)    /* ----- Si c'est un ELSE IF ----- */
  4609.                                         {
  4610.                                                 condition = testlog(conf, param[0]);
  4611.                                                 if (!conf->ifwhile[conf->nwhile].execute && conf->ifwhile[conf->nwhile].type == 1)
  4612.                                                 {
  4613.                                                         if (condition)
  4614.                                                         {
  4615.                                                                 conf->ifwhile[conf->nwhile].execute = TRUE;
  4616.                                                                 if (conf->ifwhile[conf->nwhile-1].sortie) conf->ifwhile[conf->nwhile].sortie = TRUE;    /* seulement si le niveau precedent est TRUE */
  4617.                                                                 conf->ifwhile[conf->nwhile].type = 2;
  4618.                                                         }
  4619.                                                 }
  4620.                                                 else
  4621.                                                 {
  4622.                                                         conf->ifwhile[conf->nwhile].execute = FALSE;
  4623.                                                         conf->ifwhile[conf->nwhile].sortie = FALSE;
  4624.                                                         conf->ifwhile[conf->nwhile].type = 2;
  4625.                                                 }
  4626.                                         }
  4627.                                         else    /* ----- Si c'est un ELSE classique ----- */
  4628.                                         {
  4629.                                                 if (!conf->ifwhile[conf->nwhile].execute && conf->ifwhile[conf->nwhile].type == 1)
  4630.                                                 {
  4631.                                                         conf->ifwhile[conf->nwhile].execute = TRUE;
  4632.                                                         if (conf->ifwhile[conf->nwhile-1].sortie) conf->ifwhile[conf->nwhile].sortie = TRUE;    /* seulement si le niveau precedent est TRUE */
  4633.                                                 }
  4634.                                                 else
  4635.                                                 {
  4636.                                                         conf->ifwhile[conf->nwhile].execute = FALSE;
  4637.                                                         conf->ifwhile[conf->nwhile].sortie = FALSE;
  4638.                                                 }
  4639.                                                 conf->ifwhile[conf->nwhile].type = 2;
  4640.                                         }
  4641.                                 }
  4642.                         }
  4643.                         else    /* Erreur */
  4644.                         {
  4645.                                 imprime(conf, "%s", "Erreur, ce tag ELSE n'est pas associe a un IF !");
  4646.                         }
  4647.                 }
  4648.                 /*----------------------------------------------------------------*/
  4649.                 /* ENDIF                                                          */
  4650.                 /*----------------------------------------------------------------*/
  4651.                 else if (!strncasecmp(elts[0].key,"endif",5) && conf->nwhile < N_WHILE)
  4652.                 {
  4653.                         if (conf->nwhile > 0 && conf->ifwhile[conf->nwhile].type == 1 || conf->ifwhile[conf->nwhile].type == 2)
  4654.                         {
  4655.                                 conf->nwhile--;
  4656.                         }
  4657.                         else    /* Erreur */
  4658.                         {
  4659.                                 imprime(conf, "%s", "Erreur, ce tag ENDIF n'est pas associe a un IF !");
  4660.                         }
  4661.                 }
  4662.                 else
  4663.                 {
  4664.                         if ((param[0] = ap_table_get(conf->tag,"if")) == NULL) condition = TRUE;
  4665.                         else condition = testlog(conf, param[0]);
  4666.  
  4667.                         /*----------------------------------------------------------------*/
  4668.                         /* WHILE                                                          */
  4669.                         /*----------------------------------------------------------------*/
  4670.                         if (!strcasecmp(elts[0].key,"while") && conf->nwhile < N_WHILE)
  4671.                         {
  4672.                                 if (conf->ifwhile[conf->nwhile++].execute && condition)
  4673.                                 {
  4674.                                         conf->ifwhile[conf->nwhile].ligne = conf->ligne;        /* Memorise le numero de ligne actuel */
  4675.                                         conf->ifwhile[conf->nwhile].sortie = conf->ifwhile[conf->nwhile-1].sortie;
  4676.                                         conf->ifwhile[conf->nwhile].execute = TRUE;     /* Par defaut */
  4677.                                         conf->ifwhile[conf->nwhile].tour = 0;   /* Nbr de tour effectue */
  4678.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"limit"))) == NULL) param[0] = "-1";
  4679.                                         conf->ifwhile[conf->nwhile].limite = atoi(param[0]);    /* Nombre maximum de tour que la boucle doit effectue */
  4680.  
  4681.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"type"))) == NULL) param[0] = "";   /* Le type */
  4682.                                         /* ----- type IF: 1 et 2 ----- */
  4683.                                         /* ----- type MYSQL: 3 et 4 ----- */
  4684.                                         if (!strncasecmp(param[0], "mysql", 5))
  4685.                                         {
  4686.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "mysql"))) != NULL) x = atoi(param[1]);    /* Le numero de structure */
  4687.                                                 else x = conf->mysql_def;
  4688.  
  4689.                                                 if (x >= 0 && x < N_MYSQL)
  4690.                                                 {
  4691.                                                         if (conf->base_mysql[x].fquery) /* Si il y a une requete en cour */
  4692.                                                         {
  4693.                                                                 conf->ifwhile[conf->nwhile].num = x;
  4694.                                                                 /* ---------- MYSQL / MYSQLROWS ---------- */
  4695.                                                                 if ((!strcasecmp(param[0], "mysql") || !strncasecmp(param[0], "mysqlrow", 8)) && md_mysql_nbrrows(&conf->base_mysql[x]) > 0)
  4696.                                                                 {
  4697.                                                                         md_mysql_dataseek(&conf->base_mysql[x], 0);     /* se positionne sur le 1er enregistrement */
  4698.                                                                         conf->ifwhile[conf->nwhile].type = 3;   /* Type MysqlRows */
  4699.                                                                 }
  4700.                                                                 /* ---------- MYSQLFIELDS ---------- */
  4701.                                                                 else if (!strncasecmp(param[0], "mysqlfield", 10) && md_mysql_nbrfields(&conf->base_mysql[x]) > 0)
  4702.                                                                 {
  4703.                                                                         md_mysql_fieldseek(&conf->base_mysql[x], 0);    /* se positionne sur le 1er champ */
  4704.                                                                         conf->ifwhile[conf->nwhile].type = 4;   /* Type MysqlFields */
  4705.                                                                 }
  4706.                                                                 else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4707.                                                         }
  4708.                                                         else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4709.                                                 }
  4710.                                                 else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4711.                                         }
  4712.                                         /* ----- type UPLOAD: 5 ----- */
  4713.                                         else if (!strncasecmp(param[0], "upload", 6) && conf->nupload > 0)
  4714.                                         {
  4715.                                                 conf->upload_num = 0;   /* se positionne sur le 1er champ */
  4716.                                                 conf->ifwhile[conf->nwhile].type = 5;   /* Type Upload */
  4717.                                         }
  4718.                                         /* ----- type HEADER: 6 ----- */
  4719.                                         else if (!strncasecmp(param[0], "header", 6))
  4720.                                         {
  4721.                                                 conf->ifwhile[conf->nwhile].arr = ap_table_elts(r->headers_in)/* Memorise le array */
  4722.                                                 if (conf->ifwhile[conf->nwhile].arr->nelts > 0)
  4723.                                                 {
  4724.                                                         conf->headers_in_num = 0;       /* se positionne sur le premier elements */
  4725.                                                         conf->ifwhile[conf->nwhile].type = 6;   /* Type HEADER */
  4726.                                                 }
  4727.                                                 else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4728.                                         }
  4729.                                         /* ----- type FORM: 7 ----- */
  4730.                                         else if (!strncasecmp(param[0], "form", 4))
  4731.                                         {
  4732.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag,"form"))) == NULL) x = conf->form_def;      /* Le numero de structure par defaut */
  4733.                                                 else x = atoi(param[1]);        /* Numero de structure */
  4734.  
  4735.                                                 if (x >= 0 && x < N_FORM)
  4736.                                                 {
  4737.                                                         conf->ifwhile[conf->nwhile].arr = ap_table_elts(conf->form[x].tab);     /* Memorise le array */
  4738.                                                         if (conf->ifwhile[conf->nwhile].arr->nelts > 0)
  4739.                                                         {
  4740.                                                                 conf->ifwhile[conf->nwhile].num = x;    /* Memorise le numero de la structure */
  4741.                                                                 conf->form[x].pos = 0/* se positionne sur le premier elements */
  4742.                                                                 conf->ifwhile[conf->nwhile].type = 7;   /* Type FORM */
  4743.                                                         }
  4744.                                                         else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4745.                                                 }
  4746.                                                 else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4747.                                         }
  4748.                                         /* ----- type COOKIE: 8 ----- */
  4749.                                         else if (!strncasecmp(param[0], "cookie", 6))
  4750.                                         {
  4751.                                                 conf->ifwhile[conf->nwhile].arr = ap_table_elts(conf->cookies.tab);     /* Memorise le array */
  4752.                                                 if (conf->ifwhile[conf->nwhile].arr->nelts > 0)
  4753.                                                 {
  4754.                                                         conf->cookies.pos = 0/* se positionne sur le premier elements */
  4755.                                                         conf->ifwhile[conf->nwhile].type = 8;   /* Type COOKIE */
  4756.                                                 }
  4757.                                                 else conf->ifwhile[conf->nwhile].type = 0;      /* Type Rien */
  4758.                                         }
  4759.                                         else conf->ifwhile[conf->nwhile].type = 0;      /* type Rien */
  4760.  
  4761.                                         conf->ifwhile[conf->nwhile].position = conf->pos_fichier;       /* Memorise la position dans le fichier en cour */
  4762.                                 }
  4763.                                 else conf->ifwhile[conf->nwhile].type = 0;      /* type = rien */
  4764.  
  4765.                                 /* ---------- Si type = 0 (rien) alors coupe la sortie et l'execution ---------- */
  4766.                                 if (conf->ifwhile[conf->nwhile].type == 0)
  4767.                                 {
  4768.                                         conf->ifwhile[conf->nwhile].sortie = FALSE;
  4769.                                         conf->ifwhile[conf->nwhile].execute = FALSE;
  4770.                                 }
  4771.                         }
  4772.                         /*----------------------------------------------------------------*/
  4773.                         /* WEND / WHILE_ADD ou WHILEADD                                   */
  4774.                         /*----------------------------------------------------------------*/
  4775.                         else if (!strcasecmp(elts[0].key, "wend") || !strcasecmp(elts[0].key, "while_add") || !strcasecmp(elts[0].key, "whileadd"))
  4776.                         {
  4777.                                 if (conf->nwhile > 0)   /* Si on est dans une boucle ou un if, ... */
  4778.                                 {
  4779.                                         flag = FALSE;
  4780.                                         if (++conf->ifwhile[conf->nwhile].tour < conf->ifwhile[conf->nwhile].limite || conf->ifwhile[conf->nwhile].limite < 0)
  4781.                                         {
  4782.                                                 switch(conf->ifwhile[conf->nwhile].type)
  4783.                                                 {
  4784.                                                 /* ----- Type If ----- */
  4785.                                                 case 1/* Erreur a prevoir */
  4786.                                                 case 2/* Idem */
  4787.                                                                 break;
  4788.                                                 /* ----- Type Mysql / MysqlRows ----- */
  4789.                                                 case 3: flag = md_mysql_add_dataseek(&conf->base_mysql[conf->ifwhile[conf->nwhile].num], 1);
  4790.                                                                 break;
  4791.                                                 /* ----- Type MysqlFields ----- */
  4792.                                                 case 4: flag = md_mysql_add_fieldseek(&conf->base_mysql[conf->ifwhile[conf->nwhile].num], 1);
  4793.                                                                 break;
  4794.                                                 /* ----- Type Upload ----- */
  4795.                                                 case 5: if (++conf->upload_num < conf->nupload) flag = TRUE;
  4796.                                                                 break;
  4797.                                                 /* ----- Type Header ----- */
  4798.                                                 case 6: temp_arr = ap_table_elts(r->headers_in);
  4799.                                                                 if (++conf->headers_in_num < conf->ifwhile[conf->nwhile].arr->nelts) flag = TRUE;
  4800.                                                                 break;
  4801.                                                 /* ----- Type Form ----- */
  4802.                                                 case 7: temp_arr = ap_table_elts(conf->form[conf->ifwhile[conf->nwhile].num].tab);
  4803.                                                                 if (++conf->form[conf->ifwhile[conf->nwhile].num].pos < conf->ifwhile[conf->nwhile].arr->nelts) flag = TRUE;
  4804.                                                                 break;
  4805.                                                 /* ----- Type Cookie ----- */
  4806.                                                 case 8: temp_arr = ap_table_elts(conf->cookies.tab);
  4807.                                                                 if (++conf->cookies.pos < conf->ifwhile[conf->nwhile].arr->nelts) flag = TRUE;
  4808.                                                                 break;
  4809.                                                 default: break;
  4810.                                                 }
  4811.                                         }
  4812.  
  4813.                                         if (strcasecmp(elts[0].key, "while_add") && strcasecmp(elts[0].key, "whileadd"))
  4814.                                         {
  4815.                                                 if (flag)
  4816.                                                 {
  4817.                                                         conf->pos_fichier = conf->ifwhile[conf->nwhile].position;       /* Revien au debut de la boucle */
  4818.                                                         conf->ligne = conf->ifwhile[conf->nwhile].ligne;                        /* Restore le numero de ligne tel qu'il etait au debut de la boucle */
  4819.                                                 }
  4820.                                                 else --conf->nwhile;
  4821.                                         }
  4822.                                         else if (!flag)
  4823.                                         {
  4824.                                                 conf->ifwhile[conf->nwhile].type = 0;   /* type Rien */
  4825.                                                 conf->ifwhile[conf->nwhile].sortie = FALSE;
  4826.                                                 conf->ifwhile[conf->nwhile].execute = FALSE;
  4827.                                         }
  4828.                                 }
  4829.                                 else
  4830.                                 {
  4831.                                         /* Erreur a prevoir */
  4832.                                 }
  4833.                         }
  4834.                         /*----------------------------------------------------------------*/
  4835.                         /*----------------------------------------------------------------*/
  4836.                         /* Si l'execution des tag et fonction est permise                 */
  4837.                         /*----------------------------------------------------------------*/
  4838.                         /*----------------------------------------------------------------*/
  4839.                         else if (conf->ifwhile[conf->nwhile].execute && condition)
  4840.                         {
  4841.                                 /*----------------------------------------------------------------*/
  4842.                                 /* ? ou PRINT...                                                  */
  4843.                                 /*----------------------------------------------------------------*/
  4844.                                 if (!strcmp(elts[0].key, "?") || !strncasecmp(elts[0].key, "print", 5))
  4845.                                 {
  4846.                                         if (ap_table_get(conf->tag,"interp") == NULL)   /* Simple affichage */
  4847.                                         {
  4848.                                                 imprime(conf, "%s", valeur);
  4849.                                         }
  4850.                                         else    /* ReAnalyse pour interpreter les tags */
  4851.                                         {
  4852.                                                 x = conf->pos_fichier;  /* Memorise la position */
  4853.                                                 i = conf->taille_fichier;       /* Recupere la taille */
  4854.                                                 z = conf->ligne;        /* Recupere le numero de la ligne courante du fichier */
  4855.                                                 conf->pos_fichier = 0/* Se positionne au debut */
  4856.                                                 conf->taille_fichier = strlen(valeur)/* place la nouvelle taille */
  4857.                                                 param[6] = conf->filename;
  4858.                                                 conf->filename = "-VaR!";
  4859.                                                 pool_temp = conf->pool_tag;     /* Sauve le pool actuel */
  4860.                                                 conf->pool_tag = ap_make_sub_pool(conf->pool_session)/* Cree un sous-pool temporaire */
  4861.                                                 analyse_page(r, valeur);
  4862.                                                 ap_destroy_pool(conf->pool_tag);        /* Detruit le pool temporaire */
  4863.                                                 conf->pool_tag = pool_temp;     /* recupere l'ancien pool */
  4864.                                                 conf->filename = param[6];
  4865.                                                 conf->pos_fichier = x;  /* Restore la position */
  4866.                                                 conf->taille_fichier = i;       /* Restore la taille */
  4867.                                                 conf->ligne = z;        /* Restore le numero de ligne courant */
  4868.                                                 if (conf->exit) return/* Si exit = TRUE, alors il faut tout arreter */
  4869.                                         }
  4870.                                 }
  4871.                                 /*----------------------------------------------------------------*/
  4872.                                 /* BREAK                                                          */
  4873.                                 /*----------------------------------------------------------------*/
  4874.                                 else if (!strcasecmp(elts[0].key, "break"))
  4875.                                 {
  4876.                                         if (conf->nwhile > 0)   /* Si on est pas au niveau 0 */
  4877.                                         {
  4878.                                                 x = conf->ifwhile[conf->nwhile].type;
  4879.                                                 if (x == 1 || x == 2)
  4880.                                                 {
  4881.                                                         /* Erreur : BREAK impossible dans un IF */
  4882.                                                 }
  4883.                                                 else    /* Prepare la sortie de la boucle */
  4884.                                                 {       
  4885.                                                         conf->ifwhile[conf->nwhile].type = 0;   /* type Rien */
  4886.                                                         conf->ifwhile[conf->nwhile].sortie = FALSE;
  4887.                                                         conf->ifwhile[conf->nwhile].execute = FALSE;
  4888.                                                 }
  4889.                                         }
  4890.                                 }
  4891.                                 /*----------------------------------------------------------------*/
  4892.                                 /* CRLF                                                           */
  4893.                                 /*----------------------------------------------------------------*/
  4894.                                 else if (!strcasecmp(elts[0].key, "crlf")) imprime(conf, "%s", "\r\n");
  4895.                                 /*----------------------------------------------------------------*/
  4896.                                 /* CR                                                             */
  4897.                                 /*----------------------------------------------------------------*/
  4898.                                 else if (!strcasecmp(elts[0].key, "cr")) imprime(conf, "%s", "\r");
  4899.                                 /*----------------------------------------------------------------*/
  4900.                                 /* LF                                                             */
  4901.                                 /*----------------------------------------------------------------*/
  4902.                                 else if (!strcasecmp(elts[0].key, "lf")) imprime(conf, "%s", "\n");
  4903.                                 /*----------------------------------------------------------------*/
  4904.                                 /* ?CALC...                                                       */
  4905.                                 /*----------------------------------------------------------------*/
  4906.                                 else if (!strncasecmp(elts[0].key, "?calc", 5) || !strncasecmp(elts[0].key, "?num", 4))
  4907.                                 {
  4908.                                         if (if_sortie)
  4909.                                         {
  4910.                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag,"type"))) != NULL)
  4911.                                                 {
  4912.                                                         if (strcmp(param[0], "-") && strcmp(param[0], "+") && strcmp(param[0], "0")) param[0] = "";
  4913.                                                 }
  4914.                                                 else param[0] = "";
  4915.  
  4916.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag,"len"))) != NULL) x = atoi(param[1]);       /* Largeur */
  4917.                                                 else x = 0;
  4918.  
  4919.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag,"dec"))) != NULL) i = atoi(param[1]);       /* Precision */
  4920.                                                 else i = 2;
  4921.  
  4922.                                                 param[1] = ap_psprintf(conf->pool_tag, "%%%s%d.%dlf", param[0], x, i);
  4923.                                                 if (!strncasecmp(elts[0].key , "?num", 4))      /* TAG ?NUM */
  4924.                                                 {
  4925.                                                         if ((temp = strchr(valeur, ',')) != NULL) temp[0] = '.';        /* Remplacer la virgule par un point pour que atof() convertisse correctement */
  4926.                                                         imprime(conf, param[1], atof(valeur))/* Imprime la valeur si sortie = TRUE */
  4927.                                                         if (temp != NULL) temp[0] = ',';        /* Remettre la virgule */
  4928.                                                 }
  4929.                                                 else    /* TAG ?CALC */
  4930.                                                 {
  4931.                                                         imprime(conf, param[1], calc(conf, valeur));    /* Imprime vers le client si sortie = TRUE */
  4932.                                                 }
  4933.                                         }
  4934.                                 }
  4935.                                 /*----------------------------------------------------------------*/
  4936.                                 /* SHOW                                                           */
  4937.                                 /*----------------------------------------------------------------*/
  4938.                                 else if (!strcasecmp(elts[0].key, "show"))
  4939.                                 {
  4940.                                         if (!strcasecmp(valeur, "off") || !strcasecmp(valeur, "no") || (isnum(valeur) && atoi(valeur))) conf->show = FALSE;
  4941.                                         else conf->show = TRUE;
  4942.                                 }
  4943.                                 /*----------------------------------------------------------------*/
  4944.                                 /* NOTAGBR                                                        */
  4945.                                 /*----------------------------------------------------------------*/
  4946.                                 else if (!strcasecmp(elts[0].key, "notagbr"))
  4947.                                 {
  4948.                                         if (!strcasecmp(valeur, "off") || !strcasecmp(valeur, "non") || !strcasecmp(valeur, "no") || (isnum(valeur) && atoi(valeur))) conf->notagbr = FALSE;
  4949.                                         conf->notagbr = TRUE;   /* Interdit les retour chariot apres un TAG proprietaire */
  4950.                                 }
  4951.                                 /*----------------------------------------------------------------*/
  4952.                                 /* EXIT                                                           */
  4953.                                 /*----------------------------------------------------------------*/
  4954.                                 else if (!strncasecmp(elts[0].key, "exit", 4))
  4955.                                 {
  4956.                                         /* ---------- EXIT ---------- */
  4957.                                         if (!strcasecmp(elts[0].key, "exit"))
  4958.                                         {
  4959.                                                 conf->exit = TRUE;      /* Afin de sortir completement, meme si ont est dans un include ou autre sous-page */
  4960.                                                 return;
  4961.                                         }
  4962.                                         /* ---------- EXITINC... ---------- */
  4963.                                         else if (!strncasecmp(elts[0].key, "exitinc", 7)) conf->pos_fichier = conf->taille_fichier;     /* Se positionne a la fin du fichier */
  4964.                                 }
  4965.                                 /*----------------------------------------------------------------*/
  4966.                                 /* NOHEADER                                                       */
  4967.                                 /*----------------------------------------------------------------*/
  4968.                                 else if (!strcasecmp(elts[0].key, "noheader")) conf->noheader = TRUE;   /* Afin que l'header ne soit pas envoye */
  4969.                                 /*----------------------------------------------------------------*/
  4970.                                 /* HEADER...                                                      */
  4971.                                 /*----------------------------------------------------------------*/
  4972.                                 else if (!strncasecmp(elts[0].key, "header", 6))
  4973.                                 {
  4974.                                         if (!conf->header)      /* Si aucun header n'a encore ete envoye */
  4975.                                         {
  4976.                                                 /* ---------- HEADER ---------- */
  4977.                                                 if (!strcasecmp(elts[0].key, "header"))
  4978.                                                 {
  4979.                                                         if (!strcasecmp(valeur, "no") || (isnum(valeur) && !atoi(valeur))) conf->noheader = TRUE;
  4980.                                                         else conf->noheader = FALSE;
  4981.                                                 }
  4982.                                                 /* ---------- HEADERAUTH... ---------- */
  4983.                                                 else if (!strncasecmp(elts[0].key, "headerauth", 10))
  4984.                                                 {
  4985.                                                         if (!conf->header)
  4986.                                                         {
  4987.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "type"))) == NULL) param[0] = "Basic";
  4988.                                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "name"))) == NULL) param[1] = "ADML Authenticate";
  4989.  
  4990.                                                                 r->status = HTTP_UNAUTHORIZED;
  4991.                                                                 param[2] = ap_psprintf(conf->pool_tag, "%s \"%s\"", param[0], param[1]);
  4992.                                                                 ap_table_set(r->headers_out, "WWW-authenticate", param[2]);
  4993.                                                         }
  4994.                                                         else
  4995.                                                         {
  4996.                                                                 /* WARNING: la commande HeaderAuth ne sert a rien puisque l'Header a deja ete envoye */
  4997.                                                         }
  4998.                                                 }
  4999.                                                 /* ---------- HEADERLOC... ---------- */
  5000.                                                 else if (!strncasecmp(elts[0].key, "headerloc", 9))
  5001.                                                 {
  5002.                                                         ap_table_set(r->headers_out, "Location", valeur);       /* Ajoute l'element Location a l'header */
  5003.                                                         r->status = HTTP_MOVED_TEMPORARILY;
  5004.                                                         ap_send_http_header(conf->r);   /* Envoie l'header au client */
  5005.                                                         conf->header = TRUE;
  5006.                                                         conf->exit = TRUE;      /* Afin de sortir completement, meme si ont est dans un include ou autre sous-page */
  5007.                                                         return;
  5008.                                                 }
  5009.                                                 /* ---------- HEADEREXPIR... ---------- */
  5010.                                                 else if (!strncasecmp(elts[0].key, "headerexpir", 11))
  5011.                                                 {
  5012.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "value"))) == NULL) param[0] = "0";
  5013.                                                         ap_table_set(r->headers_out, "Expires", ap_gm_timestr_822(conf->pool_tag, r->request_time + (time_t)atoi(param[0])));      /* Ajoute un element Expires a l'header */
  5014.                                                 }
  5015.                                                 /* ---------- HEADERADD... ---------- */
  5016.                                                 if (!strncasecmp(elts[0].key, "headeradd", 9))
  5017.                                                 {
  5018.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "name"))) != NULL)
  5019.                                                         {
  5020.                                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag,"value"))) == NULL) param[1] = "";
  5021.                                                                 ap_table_set(r->headers_out, param[0], param[1]);       /* Ajoute un element a l'header */
  5022.                                                         }
  5023.                                                 }
  5024.                                                 /* ---------- HEADERDEL... ---------- */
  5025.                                                 if (!strncasecmp(elts[0].key, "headerdel", 9))
  5026.                                                 {
  5027.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"name"))) != NULL) ap_table_unset(r->headers_out, param[0]);
  5028.                                                 }
  5029.                                                 /* ---------- HEADERCOOKIE... ---------- */
  5030.                                                 if (!strncasecmp(elts[0].key, "headercook", 10))
  5031.                                                 {
  5032.                                                         if ((param[4] = interp(conf, ap_table_get(conf->tag,"name"))) != NULL)
  5033.                                                         {
  5034.                                                                 if ((param[5] = interp(conf, ap_table_get(conf->tag,"value"))) == NULL) param[5] = "";
  5035.  
  5036.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag,"expire"))) == NULL) param[0] = "";
  5037.                                                                 else
  5038.                                                                 {
  5039.                                                                         z = atoi(param[0]) + (int)time(&secs);
  5040.                                                                         param[0] = ap_psprintf(conf->pool_tag, "; expires=%s", ap_gm_timestr_822(conf->pool_tag, z));
  5041.                                                                 }
  5042.  
  5043.                                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag,"path"))) == NULL) param[1] = "";
  5044.                                                                 else param[1] = ap_psprintf(conf->pool_tag, "; path=%s", param[1]);
  5045.  
  5046.                                                                 if ((param[2] = interp(conf, ap_table_get(conf->tag,"domain"))) == NULL) param[2] = "";
  5047.                                                                 else param[2] = ap_psprintf(conf->pool_tag, "; domain=%s", param[2]);
  5048.  
  5049.                                                                 if ((param[3] = interp(conf, ap_table_get(conf->tag,"secure"))) == NULL) param[3] = "";
  5050.                                                                 else param[3] = "; secure";
  5051.  
  5052.                                                                 param[6] = ap_psprintf(conf->pool_tag, "%s=%s%s%s%s%s", param[4], param[5], param[0], param[1], param[2], param[3]);
  5053.  
  5054.                                                                 ap_table_add(r->headers_out, "Set-Cookie", param[6]);   /* Ajoute un cookie a l'header */
  5055.                                                         }
  5056.                                                 }
  5057. /*
  5058.                                                 else
  5059.                                                 {
  5060.                                                         temp_arr = ap_table_elts(r->headers_out);
  5061.                                                         temp_elts = (table_entry *) temp_arr->elts;
  5062.                                                         for(x=0; x < temp_arr->nelts; x++)
  5063.                                                         {
  5064. ap_rprintf(r, " [%s]=[%s]<BR> ", temp_elts[x].key, temp_elts[x].val);
  5065.                                                         }
  5066.                                                 }
  5067. */
  5068.                                         }
  5069.                                 }
  5070.                                 /*----------------------------------------------------------------*/
  5071.                                 /* OPTION...                                                      */
  5072.                                 /*----------------------------------------------------------------*/
  5073.                                 else if (!strncasecmp(elts[0].key, "option", 6))
  5074.                                 {
  5075.                                         if (if_sortie)  /* Si ont peut imprimer vers le client */
  5076.                                         {
  5077.                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag,"selected"))) == NULL) y = 0;
  5078.                                                 else y = atoi(param[0]);        /* Recupere la valeur de test pour la selection */
  5079.        
  5080.                                                 /* ---------- OPTIONNUM ou OPTIONYEAR ---------- */
  5081.                                                 if (!strcasecmp(elts[0].key, "optionyear") || !strncasecmp(elts[0].key, "optionnum", 9))
  5082.                                                 {
  5083.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"start"))) != NULL) x = atoi(param[0]);     /* Valeur de depart */
  5084.                                                         else x = 0;
  5085.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"len"))) != NULL) z = x + atoi(param[0]);   /* Fin */
  5086.                                                         else z = x;
  5087.  
  5088.                                                         if (z >= x) /* Incrementation */
  5089.                                                         {
  5090.                                                                 for (i = x; i < z; i++)
  5091.                                                                 {
  5092.                                                                         if (i == y) param[0] = "SELECTED ";
  5093.                                                                         else param[0] = "";
  5094.                                                                         imprime(conf, "<OPTION %sVALUE=\"%d\">%d</OPTION>", param[0], i, i);
  5095.                                                                 }
  5096.                                                         }
  5097.                                                         else    /* Decrementation */
  5098.                                                         {
  5099.                                                                 for (i = x; i > z; i--)
  5100.                                                                 {
  5101.                                                                         if (i == y) param[0] = "SELECTED ";
  5102.                                                                         else param[0] = "";
  5103.                                                                         imprime(conf, "<OPTION %sVALUE=\"%d\">%d</OPTION>", param[0], i, i);
  5104.                                                                 }
  5105.                                                         }
  5106.                                                 }
  5107.                                                 else
  5108.                                                 {
  5109.                                                         x = 0/* francais par defaut */
  5110.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"lang"))) != NULL)
  5111.                                                         {
  5112.                                                                 if (!strncasecmp(param[0], "num_en", 6)) x = -2;        /* Numerique anglais */
  5113.                                                                 else if (!strncasecmp(param[0], "num", 3)) x = -1;      /* Numerique Francais */
  5114.                                                                 else if (!strncasecmp(param[0], "a_fr", 4)) x = 1;      /* Francais abreger */
  5115.                                                                 else if (!strncasecmp(param[0], "en", 2)) x = 2;        /* Anglais */
  5116.                                                                 else if (!strncasecmp(param[0], "a_en", 4)) x = 3;      /* Anglais Abreger */
  5117.                                                                 else if (!strncasecmp(param[0], "de", 2)) x = 4;        /* Allemand */
  5118.                                                                 else if (!strncasecmp(param[0], "a_de", 4)) x = 5;      /* Allemand Abreger */
  5119.                                                         }
  5120.  
  5121.                                                         /* ---------- OPTIONMONTH ---------- */
  5122.                                                         if (!strcasecmp(elts[0].key, "optionmonth"))
  5123.                                                         {
  5124.                                                                 for (i = 0; i < 12; i++)
  5125.                                                                 {
  5126.                                                                         if (i+1 == y) param[0] = "SELECTED ";
  5127.                                                                         else param[0] = "";
  5128.                                                                         if (x >= 0) imprime(conf, "<OPTION %sVALUE=\"%d\">%s</OPTION>", param[0], i+1, mois[x][i]);     /* Affichage des noms de mois */
  5129.                                                                         else imprime(conf, "<OPTION %sVALUE=\"%d\">%d</OPTION>", param[0], i+1, i+1);   /* Affichage numerique */
  5130.                                                                 }
  5131.                                                         }
  5132.                                                         /* ---------- OPTIONDAY ---------- */
  5133.                                                         else if (!strcasecmp(elts[0].key, "optionday"))
  5134.                                                         {
  5135.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag,"month"))) != NULL) x = atoi(param[0]);     /* Mois */
  5136.                                                                 else x = 0;
  5137.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag,"year"))) != NULL) w = atoi(param[0]);      /* Annee */
  5138.                                                                 else w = 0;
  5139.  
  5140.                                                                 if (x > 0 && x < 13 && w > 0) z = jour_dans_mois[annee_bissex(w)][x];   /* Nombre de jour du mois */
  5141.                                                                 else z = 31;
  5142.  
  5143.                                                                 for (i = 1; i <= z; i++)
  5144.                                                                 {
  5145.                                                                         if (i == y) param[0] = "SELECTED ";
  5146.                                                                         else param[0] = "";
  5147.                                                                         imprime(conf, "<OPTION %sVALUE=\"%d\">%02d</OPTION>", param[0], i, i);
  5148.                                                                 }
  5149.                                                         }
  5150.                                                         /* ---------- OPTIONDAYWEEK ---------- */
  5151.                                                         else if (!strncasecmp(elts[0].key, "optiondayweek", 13))
  5152.                                                         {
  5153.                                                                 for (i = 0; i < 7; i++)
  5154.                                                                 {
  5155.                                                                         if (i+1 == y) param[0] = "SELECTED ";
  5156.                                                                         else param[0] = "";
  5157.                                                                         if (x > 1 || x < -1 || i > 0)
  5158.                                                                         {
  5159.                                                                                 if (x >= 0) imprime(conf, "<OPTION %sVALUE=\"%d\">%s</OPTION>", param[0], i+1, jour[x][i]);     /* Affichage des noms de jour */
  5160.                                                                                 else
  5161.                                                                                 {
  5162.                                                                                         if (x < -1) imprime(conf, "<OPTION %sVALUE=\"%d\">%d</OPTION>", param[0], i+1, i+1);    /* Affichage numerique Anglais */
  5163.                                                                                         else imprime(conf, "<OPTION %sVALUE=\"%d\">%d</OPTION>", param[0], i+1, i);     /* Affichage numerique Francais */
  5164.                                                                                 }
  5165.                                                                         }
  5166.                                                                 }
  5167.                                                                 if (y == 1) param[0] = "SELECTED ";
  5168.                                                                 else param[0] = "";
  5169.                                                                 if (x < 2 && x >= 0) imprime(conf, "<OPTION %sVALUE=\"1\">%s</OPTION>", param[0], jour[x][0])/* Ajoute le dimanche a la fin pour le francais */
  5170.                                                                 else if (x == -1) imprime(conf, "<OPTION %sVALUE=\"1\">7</OPTION>", param[0])/* Ajoute le numero du dimanche a la fin pour le francais */
  5171.                                                         }
  5172.                                                 }
  5173.                                         }
  5174.                                 }
  5175.                                 /*----------------------------------------------------------------*/
  5176.                                 /* CONFIG...                                                      */
  5177.                                 /*----------------------------------------------------------------*/
  5178.                                 else if (!strncasecmp(elts[0].key, "config", 6))
  5179.                                 {
  5180.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"mysql"))) != NULL)
  5181.                                         {
  5182.                                                 x = atoi(param[0]);
  5183.                                                 if (x >= 0 && x < N_MYSQL) conf->mysql_def = x; /* redefinit la valeur par defaut */
  5184.                                         }
  5185.  
  5186.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"form"))) != NULL)
  5187.                                         {
  5188.                                                 x = atoi(param[0]);
  5189.                                                 if (x >= 0 && x < N_FORM) conf->form_def = x;   /* redefinit la valeur par defaut */
  5190.                                         }
  5191.  
  5192.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"var"))) != NULL)
  5193.                                         {
  5194.                                                 x = atoi(param[0]);
  5195.                                                 if (x >= 0 && x < N_VAR) conf->var_def = x;     /* redefinit la valeur par defaut */
  5196.                                         }
  5197. /*
  5198. ----> IL NE FAUT PAS CHANGER LA CONFIG RECUPERER DANS HTTPD.CONF CAR IL Y AURAIT UN PROBLEME SUR LE PROCESS QUI RECOIT D'AUTRES REQUETE ENSUITE ET NE CONNAIT PLUS LA CONFIG
  5199.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"mysqlhost"))) != NULL) conf->mysql_host = ap_pstrdup(conf->pool_session, param[0]);
  5200.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"mysqluser"))) != NULL) conf->mysql_user = ap_pstrdup(conf->pool_session, param[0]);
  5201.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"mysqlpassword"))) != NULL) conf->mysql_passwd = ap_pstrdup(conf->pool_session, param[0]);
  5202.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"mysqlbase"))) != NULL) conf->mysql_base = ap_pstrdup(conf->pool_session, param[0]);
  5203. */
  5204.                                 }
  5205.                                 /*----------------------------------------------------------------*/
  5206.                                 /* FLUSH                                                          */
  5207.                                 /*----------------------------------------------------------------*/
  5208.                                 else if (!strcasecmp(elts[0].key, "flush"))
  5209.                                 {
  5210.                                         /* -----> Il faudra que cette fonction n'est aucun effet si le client est un fichier en ecriture <----- */
  5211.                                                 ap_rflush(r);   /* Vide le tampon vers le client */
  5212.                                 }
  5213.                                 /*----------------------------------------------------------------*/
  5214.                                 /* SLEEP                                                          */
  5215.                                 /*----------------------------------------------------------------*/
  5216.                                 else if (!strcasecmp(elts[0].key, "sleep"))
  5217.                                 {
  5218.                                         if ((x = atoi(valeur)) > 0) sleep(x);   /* Attend x secondes */
  5219.                                 }
  5220.                                 /*----------------------------------------------------------------*/
  5221.                                 /* DATE...                                                        */
  5222.                                 /*----------------------------------------------------------------*/
  5223.                                 else if (!strncasecmp(elts[0].key, "date",4))
  5224.                                 {
  5225.                                         x = atoi(valeur);       // Numero de la structure a utiliser
  5226.  
  5227.                                         if (x < N_DATE && x > -1)       /* Si le numero de structure est correct */
  5228.                                         {
  5229.                                                 /* ---------- DATEUNIX ---------- */
  5230.                                                 if (!strcasecmp(elts[0].key, "dateunix"))
  5231.                                                 {
  5232.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"value"))) != NULL) conf->secs[x] = (time_t)atol(param[0])/* Configure la structure form specifie avec le timestamp unix du parametre value */
  5233.                                                 }
  5234.                                         }
  5235.                                 }
  5236.                                 /*----------------------------------------------------------------*/
  5237.                                 /* VAR...                                                         */
  5238.                                 /*----------------------------------------------------------------*/
  5239.                                 else if (!strncasecmp(elts[0].key, "var",3))
  5240.                                 {
  5241.                                         if (elts[0].val == NULL || strlen(elts[0].val)<1) x = conf->var_def;    /* Numero de structure par defaut */
  5242.                                         x = atoi(valeur);       // Numero de la structure a utiliser
  5243.  
  5244.                                         if (x < N_VAR && x > -1)        /* Si le numero de structure est correct */
  5245.                                         {
  5246.                                                 temp_arr = ap_table_elts(conf->var[x].tab);
  5247.                                                 temp_elts = (table_entry *) temp_arr->elts;
  5248.  
  5249.                                                 y = 0;
  5250.                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "type"))) != NULL)
  5251.                                                 {
  5252.                                                         if (!strncasecmp(param[0], "add", 3) || !strncasecmp(param[0], "init_add", 8)) y = 1;   /* Ajoute un element meme s'il y en a un qui existe deja */
  5253.                                                         else if (!strncasecmp(param[0], "arr", 3) || !strncasecmp(param[0], "init_arr", 8)) y = 2;      /* Ajoute un element en mettant dans le meme champ s'il existe et en separant par une vigule ou un espace */
  5254.                                                         else if (!strncasecmp(param[0], "if", 2) || !strncasecmp(param[0], "init_if", 7)) y = 4;        /* Ajoute un element seulement s'il existe deja et remplace l'existant */
  5255.                                                         else y = 0;     /* (UPDATE) Ajoute un element en remplacant l'ancien s'il existait */
  5256.  
  5257.                                                         if (!strncasecmp(param[0], "init", 4))  /* Clear / init */
  5258.                                                         {
  5259.                                                                 y += 8;
  5260.                                                                 conf->var[x].pos = 0;
  5261.                                                         }
  5262.                                                 }
  5263.  
  5264.                                                 /* ---------- VARADD... ---------- */
  5265.                                                 if (!strncasecmp(elts[0].key, "varadd", 6))
  5266.                                                 {
  5267.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "name"))) != NULL)
  5268.                                                         {
  5269.                                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "value"))) == NULL) param[1] = "";
  5270.                                                                 add_form(conf->var[x].tab, param[0], param[1], y);      /* Ajout du champ avec duplication de nom et value */
  5271.                                                         }
  5272.                                                 }
  5273.                                                 /* ---------- VARDEL... ---------- */
  5274.                                                 else if (!strncasecmp(elts[0].key, "vardel", 6))
  5275.                                                 {
  5276.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"name"))) != NULL)
  5277.                                                         {
  5278.                                                                 ap_table_unset(conf->var[x].tab, param[0]);     /* Supprime une entree de la table Form */
  5279.                                                         }
  5280.                                                 }
  5281.                                                 /* ---------- VARCLEAR ---------- */
  5282.                                                 else if (!strcasecmp(elts[0].key, "varclear"))
  5283.                                                 {
  5284.                                                         ap_clear_table(conf->var[x].tab);       /* Efface le contenu d'une table */
  5285.                                                         conf->var[x].pos = 0;
  5286.                                                 }
  5287.                                         }
  5288.                                 }
  5289.                                 /*----------------------------------------------------------------*/
  5290.                                 /* FORM...                                                        */
  5291.                                 /*----------------------------------------------------------------*/
  5292.                                 else if (!strncasecmp(elts[0].key, "form",4))
  5293.                                 {
  5294.                                         if (elts[0].val == NULL || strlen(elts[0].val)<1) x = conf->form_def;   /* Numero de structure par defaut */
  5295.                                         x = atoi(valeur);       // Numero de la structure a utiliser
  5296.  
  5297.                                         if (x < N_FORM && x > -1)       /* Si le numero de structure est correct */
  5298.                                         {
  5299.                                                 temp_arr = ap_table_elts(conf->form[x].tab);
  5300.                                                 temp_elts = (table_entry *) temp_arr->elts;
  5301.  
  5302.                                                 y = 0;
  5303.                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag,"type"))) != NULL)
  5304.                                                 {
  5305.                                                         if (!strncasecmp(param[0], "add", 3) || !strncasecmp(param[0], "init_add", 8)) y = 1;   /* Ajoute un element meme s'il y en a un qui existe deja */
  5306.                                                         else if (!strncasecmp(param[0], "arr", 3) || !strncasecmp(param[0], "init_arr", 8)) y = 2;      /* Ajoute un element en mettant dans le meme champ s'il existe et en separant par une vigule ou un espace */
  5307.                                                         else if (!strncasecmp(param[0], "if", 2) || !strncasecmp(param[0], "init_if", 7)) y = 4;        /* Ajoute un element seulement s'il existe deja et remplace l'existant */
  5308.                                                         else y = 0;     /* (UPDATE) Ajoute un element en remplacant l'ancien s'il existait */
  5309.  
  5310.                                                         if (!strncasecmp(param[0], "init", 4))  /* Clear / init */
  5311.                                                         {
  5312.                                                                 y += 8;
  5313.                                                                 conf->form[x].pos = 0;
  5314.                                                         }
  5315.                                                 }
  5316.  
  5317.                                                 /* ---------- FORMADD... ---------- */
  5318.                                                 if (!strncasecmp(elts[0].key, "formadd", 7))
  5319.                                                 {
  5320.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"name"))) != NULL)
  5321.                                                         {
  5322.                                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "value"))) == NULL) param[1] = "";
  5323.                                                                 add_form(conf->form[x].tab, param[0], param[1], y);     /* Ajout du champ avec duplication de nom et value */
  5324.                                                         }
  5325.                                                 }
  5326.                                                 /* ---------- FORMDEC... ---------- */
  5327.                                                 else if (!strncasecmp(elts[0].key, "formdec", 7))
  5328.                                                 {
  5329.                                                         if ((temp = interp(conf, ap_table_get(conf->tag, "value"))) != NULL)
  5330.                                                         {
  5331.                                                                 decode_classique(conf, x, temp, y, TRUE);       /* Decodage d'une chaine encoder en URL-Encoded */
  5332.                                                         }
  5333.                                                 }
  5334.                                                 /* ---------- FORMDEL... ---------- */
  5335.                                                 else if (!strncasecmp(elts[0].key, "formdel", 7))
  5336.                                                 {
  5337.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"name"))) != NULL)
  5338.                                                         {
  5339.                                                                 ap_table_unset(conf->form[x].tab, param[0]);    /* Supprime une entree de la table Form */
  5340.                                                         }
  5341.                                                 }
  5342.                                                 /* ---------- FORMCLEAR ---------- */
  5343.                                                 else if (!strcasecmp(elts[0].key, "formclear"))
  5344.                                                 {
  5345.                                                         ap_clear_table(conf->form[x].tab);      /* Efface le contenu d'une table */
  5346.                                                         conf->form[x].pos = 0;
  5347.                                                 }
  5348.                                                 /* ---------- FORMOPT... ---------- */
  5349.                                                 else if (!strncasecmp(elts[0].key, "formopt", 7))
  5350.                                                 {
  5351.                                                         if ((param[0] = ap_table_get(conf->tag,"value")) == NULL) param[0] = "";
  5352.                                                         if ((param[1] = ap_table_get(conf->tag,"text")) == NULL) param[1] = "";
  5353.                                                         if ((param[2] = interp(conf, ap_table_get(conf->tag,"selected"))) == NULL) param[2] = "";
  5354.                                                         param[3] = ap_table_get(conf->tag, "filter");
  5355.  
  5356.                                                         for(i=0; i < temp_arr->nelts; i++)
  5357.                                                         {
  5358.                                                                 conf->form[x].pos = i;  /* Position courante */
  5359.                                                                 if (param[3] != NULL) flag = testlog(conf, interp(conf, param[3]));
  5360.                                                                 else flag = TRUE;
  5361.  
  5362.                                                                 if (flag)       /* Pour le filtre */
  5363.                                                                 {
  5364.                                                                         temp = interp(conf, param[0]);
  5365.                                                                         if (!ap_strcmp_match(temp, param[2])) param[6] = "SELECTED ";
  5366.                                                                         else param[6] = "";
  5367.                                                 imprime(conf, "<OPTION %sVALUE=\"%s\">%s</OPTION>", param[6], temp, interp(conf, param[1]));
  5368.                                                                 }
  5369.                                                         }
  5370.                                                 }
  5371.                                         }
  5372.                                 }
  5373.                                 /*----------------------------------------------------------------*/
  5374.                                 /* INC...                                                         */
  5375.                                 /*----------------------------------------------------------------*/
  5376.                                 else if (!strncasecmp(elts[0].key,"inc",3))
  5377.                                 {
  5378.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"file"))) == NULL) param[0] = valeur;
  5379.                                         if ((param[1] = interp(conf, ap_table_get(conf->tag,"type"))) == NULL) param[1] = "inc";
  5380.                                         conf->rr = NULL;
  5381.  
  5382.                                         if (!strncasecmp(param[0], "http://", 7)) param[1] = "http";    /* type http obligatoirement */
  5383.        
  5384.                                         /* ----- TYPE=FILE ou TYPE=VIRT... ----- */
  5385.                                         if (!strcasecmp(param[1],"file") || !strncasecmp(param[1],"virt",4))
  5386.                                         {
  5387.                                                 if (if_sortie) conf->temp = "1";
  5388.                                                 else conf->temp = "0";
  5389.                                                 ap_table_setn(r->subprocess_env, "ADML_SHOW", conf->temp);      /* Pour que la sous requete recupere la valeur de sortie */
  5390.                                                 if (conf->ifwhile[0].execute) conf->temp = "1";
  5391.                                                 else conf->temp = "0";
  5392.                                                 ap_table_setn(r->subprocess_env, "ADML_EXEC", conf->temp);      /* Pour que la sous requete recupere la valeur de execute */
  5393.  
  5394.                                                 /* Recherche un fichier comme s'il sagissait d'une requete */
  5395.                                                 if (!strcasecmp(param[1],"file")) conf->rr = (request_rec *)ap_sub_req_lookup_file(param[0],r);
  5396.                                                 else conf->rr = (request_rec *)ap_sub_req_lookup_uri(param[0],r);
  5397.        
  5398.                                                 if (conf->rr->status != HTTP_OK) error = "unable to include \"%s\" in parsed file %s";
  5399.                
  5400.                                                 /* verification contre les include recursifs */
  5401.                                                 if (error == NULL)
  5402.                                                 {
  5403.                                                         int founddupe = 0;
  5404.                                                         request_rec *p;
  5405.                                                         for (p = r; p != NULL && !founddupe; p = p->main)
  5406.                                                         {
  5407.                                                                 request_rec *q;
  5408.                                                                 for (q = p; q != NULL; q = q->prev)
  5409.                                                                 {
  5410.                                                                         if ((strcmp(q->filename, conf->rr->filename) == 0) || (strcmp(q->uri, conf->rr->uri) == 0))
  5411.                                                                         {
  5412.                                                                                 founddupe = 1;
  5413.                                                                                 break;
  5414.                                                                         }
  5415.                                                                 }
  5416.                                                         }
  5417.                                                         if (p != NULL) error = "Recursive include of \"%s\" in parsed file %s"/* Il y a un include recursif */
  5418.                                                 }
  5419.        
  5420.                                                 memcpy(&toto, conf, sizeof(adml_cfg));    /* Effectue une copie de sauvegarde (pour l'include type=file ou virtual) */
  5421.  
  5422.                                                 if (conf->rr) ap_set_module_config(conf->rr->request_config, &adml_module, r);
  5423.        
  5424.                                                 if (!error && ap_run_sub_req(conf->rr)) error = "unable to include \"%s\" in parsed file %s";
  5425.        
  5426.                                                 memcpy(conf, &toto, sizeof(adml_cfg));    /* Recuperation de la structure sauvegarde avant l'include (au cas ou le fichier en include serait un handler adml egalement) */
  5427.  
  5428.                                                 ap_table_unset(r->subprocess_env, "ADML_SHOW")/* Supprime la variable d'environnement */
  5429.                                                 ap_table_unset(r->subprocess_env, "ADML_EXEC")/* Supprime la variable d'environnement */
  5430.                                         }
  5431.                                         /* ----- TYPE=HTTP... ----- */
  5432.                                         else if (!strncasecmp(param[1], "http", 4))
  5433.                                         {
  5434.                                                 ap_parse_uri_components(conf->pool_tag, valeur, &uptr);
  5435.                                                 if (uptr.is_initialized)
  5436.                                                 {
  5437.                                                         if (!uptr.port_str) uptr.port_str = "80";
  5438.                                                         if (uptr.query) temp = ap_pstrcat(conf->pool_tag, "?", uptr.query, NULL);
  5439.                                                         else temp = "";
  5440.  
  5441.                                                         if ((y = socket_connect(&conf->sock[N_SOCKET], uptr.hostname, uptr.port_str)) > 0)
  5442.                                                         {
  5443. /* ap_bprintf(conf->sock[N_SOCKET].f, "GET %s%s HTTP/1.0\r\nConnection: close\r\nUser-Agent: %s/%s [] (%s)\r\nHost: %s\r\n\r\n", uptr.path, temp, ADML_NOM, ADML_VERSION, ap_get_server_version(), uptr.hostname); */
  5444.                                                                 ap_bprintf(conf->sock[N_SOCKET].f, "GET %s%s HTTP/1.0\r\n", uptr.path, temp);
  5445.                                                                 ap_bprintf(conf->sock[N_SOCKET].f, "Connection: close\r\n");
  5446.                                                                 ap_bprintf(conf->sock[N_SOCKET].f, "User-Agent: %s/%s [] (%s)\r\n", ADML_NOM, ADML_VERSION, ap_get_server_version());
  5447.                                                                 ap_bprintf(conf->sock[N_SOCKET].f, "Host: %s\r\n", uptr.hostname);
  5448.                                                                 if (uptr.user != NULL)  /* USER */
  5449.                                                                 {
  5450.                                                                         if ((param[3] = uptr.password) == NULL) param[3] = ""/* PASSWORD */
  5451.                                                                         temp = ap_psprintf(conf->pool_tag, "%s:%s", uptr.user, param[3]);
  5452.                                                                         ap_bprintf(conf->sock[N_SOCKET].f, "Authorization: Basic %s\r\n", base64encode(conf->pool_tag, temp, strlen(temp), NULL));
  5453.                                                                 }
  5454.                                                                 ap_bprintf(conf->sock[N_SOCKET].f, "\r\n");
  5455.                                                                 ap_bflush(conf->sock[N_SOCKET].f);
  5456.  
  5457.                                                                 flag = FALSE;
  5458.                                                                 while((y = socket_readmsg(r, &conf->sock[N_SOCKET], conf->buffer, TAILLE_BUFFER)) > 0)
  5459.                                                                 {
  5460.                                                                         if (flag)
  5461.                                                                         {
  5462.                                                                                 imprime(conf, "%s", conf->buffer);
  5463.                                                                         }
  5464.                                                                         else
  5465.                                                                         {
  5466.                                                                                 if (!strcmp(conf->buffer, "\n") || !strcmp(conf->buffer, "\r\n")) flag = TRUE;
  5467.                                                                         }
  5468.                                                                 }
  5469.                                                                 socket_close(&conf->sock[N_SOCKET]);
  5470.                                                         }
  5471.                                                 }
  5472.                                         }
  5473.                                         /* ----- TYPE=INC... ----- */
  5474.                                         else
  5475.                                         {
  5476.                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(param[0],r);
  5477.        
  5478.                                                 if (conf->rr->finfo.st_mode == 0) error = "le fichier n'existe pas";
  5479.                                                 else
  5480.                                                 {
  5481.                                                         arr = ap_table_elts(conf->include);
  5482.                                                         elts = (table_entry *) arr->elts;
  5483.  
  5484.                                                         conf->temp = NULL;
  5485.                                                         for(x=0; x < arr->nelts; x++)
  5486.                                                         {
  5487.                                                                 if (!strcmp(elts[x].key, conf->rr->filename))
  5488.                                                                 {
  5489.                                                                         conf->temp = elts[x].val;
  5490.                                                                         break;
  5491.                                                                 }
  5492.                                                         }
  5493.  
  5494.                                                         if (conf->temp == NULL)
  5495.                                                         {
  5496.                                                                 if (!(f = ap_pfopen(conf->pool_tag, conf->rr->filename, "r")))
  5497.                                                                 {
  5498.                                                                         error = "permission denied!";
  5499.                                                                 }
  5500.                                                                 else
  5501.                                                                 {
  5502.                                                                         conf->temp = (char *) ap_pcalloc(conf->pool_session, (sizeof(char) * (conf->rr->finfo.st_size)+1));
  5503.  
  5504.                                                                         i = 0;
  5505.                                                                         while ((c = fgetc(f)) != EOF && i < conf->rr->finfo.st_size) conf->temp[i++] = c;
  5506.                                                                         conf->temp[i] = '\0';
  5507.                                                                         if (ferror(f)) fprintf(stderr,"encountered error in getc() function dans module Model");
  5508.                                                                         ap_pfclose(conf->pool_tag, f)/* Fermeture du fichier */
  5509.        
  5510.                                                                         ap_table_addn(conf->include, ap_pstrdup(conf->pool_session, conf->rr->filename), conf->temp);   /* Enregistre l'include dans la table des includes */
  5511.  
  5512.                                                                 }
  5513.                                                         }
  5514.  
  5515.                                                         if (!error)     /* Si il n'y a pas d'erreur */
  5516.                                                         {
  5517.                                                                 x = conf->pos_fichier;  /* Memorise la position */
  5518.                                                                 i = conf->taille_fichier;       /* Recupere la taille */
  5519.                                                                 z = conf->ligne;        /* Recupere le numero de la ligne courante du fichier */
  5520.                                                                 conf->taille_fichier = strlen(conf->temp);      /* Place la nouvelle taille */
  5521.                                                                 param[6] = conf->filename;
  5522.                                                                 conf->filename = ap_pstrdup(conf->pool_session, param[0]);      /* Memorise le nom du fichier include */
  5523.                                                                 analyse_page(r, conf->temp);
  5524.                                                                 conf->filename = param[6];
  5525.                                                                 conf->pos_fichier = x;  /* Restore la position */
  5526.                                                                 conf->taille_fichier = i;       /* Restore la taille */
  5527.                                                                 conf->ligne = z;        /* restore le numero de ligne courante */
  5528.                                                                 if (conf->exit) return/* Si exit = TRUE, alors il faut tout arreter */
  5529.                                                         }
  5530.                                                 }
  5531.                                         }
  5532.  
  5533. #ifndef WIN32
  5534.                                         ap_chdir_file(r->filename);
  5535. #endif
  5536.  
  5537.                                         if (error)
  5538.                                         {
  5539.                                                 ap_log_rerror(APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r, error, param[0], r->filename);
  5540.                                                 imprime(conf, "%s %s %s", error, param[0], r->filename);                /* sortie de l'erreur a l'ecran */
  5541.                                         }
  5542.                                 }
  5543.                                 /*----------------------------------------------------------------*/
  5544.                                 /* MAIL...                                                        */
  5545.                                 /*----------------------------------------------------------------*/
  5546.                                 else if (!strncasecmp(elts[0].key,"mail", 4))
  5547.                                 {
  5548.                                         if ((param[2] = interp(conf, ap_table_get(conf->tag, "to"))) != NULL)
  5549.                                         {
  5550.                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "host"))) == NULL) param[0] = "localhost";
  5551.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "service"))) == NULL) param[1] = "smtp";
  5552.                                                 if ((y = socket_connect(&conf->smtp.sock, param[0], param[1])) > 0)     /* Si la connection SOCKET est OK */
  5553.                                                 {
  5554. /* imprime(conf, "SMTP_OK=[%d]<BR> ", y); */
  5555.  
  5556.                                                         socket_gets(conf, &conf->smtp.sock);    /* Lecture d'une ligne dans le buffer socket SMTP */
  5557. /* imprime(conf, "Taille_buffer_max=[%d]<BR> ", conf->smtp.sock.taille_buffer_max); */
  5558. /* imprime(conf, "Buffer=[%s]<BR> ", conf->smtp.sock.buffer); */
  5559.                                                         if (!strncmp(conf->smtp.sock.buffer, "220", 3)) /* Si connection reussi ! */
  5560.                                                         {
  5561.                                                                 ap_bprintf(conf->smtp.sock.f, "EHLO %s\r\n", ap_get_local_host(conf->pool_tag));
  5562.                                                                 ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5563.                                                                 if ((z = smtp_retour(conf)) != 250)
  5564.                                                                 {
  5565.                                                                         ap_bprintf(conf->smtp.sock.f, "HELO %s\r\n", ap_get_local_host(conf->pool_tag));
  5566.                                                                         ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5567.                                                                         z = smtp_retour(conf);
  5568.                                                                 }
  5569.                                                                                 if ((param[3] = interp(conf, ap_table_get(conf->tag, "from"))) == NULL) param[3] = "";
  5570.                                                                                 ap_bprintf(conf->smtp.sock.f, "MAIL FROM: %s\r\n", param[3]);
  5571.                                                                                 ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5572.                                                                                 z = smtp_retour(conf);
  5573.                                                                                 ap_bprintf(conf->smtp.sock.f, "RCPT TO: %s\r\n", param[2]);
  5574.                                                                                 ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5575.                                                                                 z = smtp_retour(conf);
  5576.                                                                                 ap_bprintf(conf->smtp.sock.f, "DATA\r\n");
  5577.                                                                                 ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5578.                                                                                 z = smtp_retour(conf);
  5579.  
  5580.                                                                                 if ((param[4] = interp(conf, ap_table_get(conf->tag, "subject"))) == NULL) param[4] = "";
  5581.                                                                                 if ((param[5] = interp(conf, ap_table_get(conf->tag, "message"))) == NULL) param[5] = "";
  5582.                                                                                 ap_bprintf(conf->smtp.sock.f, "Subject: %s\r\n\r\n%s\r\n.\r\n", param[4], param[5]);
  5583.                                                                                 ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5584.                                                                                 z = smtp_retour(conf);
  5585.  
  5586.                                                                                 ap_bprintf(conf->smtp.sock.f, "QUIT\r\n");
  5587.                                                                                 ap_bflush(conf->smtp.sock.f);   /* vide le tampon */
  5588.                                                                                 z = smtp_retour(conf);
  5589.                                                         }
  5590.                                                         else    /* Si erreur de connection retourner par le serveur SMTP */
  5591.                                                         {
  5592. imprime(conf, " [%s] ", conf->smtp.sock.buffer);
  5593.                                                         }
  5594.                                                 }
  5595.                                                 else    /* Erreur de connection SOCKET */
  5596.                                                 {
  5597. imprime(conf, "erreur de connection socket SMTP [%d] ", y);
  5598.                                                 }
  5599.                                         }
  5600.                                         else    /* Erreur : pas d'adresse To */
  5601.                                         {
  5602. imprime(conf, "ERREUR: Pas d'adresse de destination (To:) ");
  5603.                                         }
  5604.                                 }
  5605.                                 /*----------------------------------------------------------------*/
  5606.                                 /* SOCK...                                                        */
  5607.                                 /*----------------------------------------------------------------*/
  5608.                                 else if (!strncasecmp(elts[0].key,"sock", 4))
  5609.                                 {
  5610.                                         x = atoi(valeur);       // Numero de la structure a utiliser
  5611.  
  5612.                                         i = 0/* type = socket */
  5613.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "type"))) != NULL)
  5614.                                         {
  5615.                                                 if (!strncasecmp(param[0], "http", 4)) i = 1;   /* type HTTP */
  5616.                                         }
  5617.  
  5618.                                         if (x >= 0 && x < N_SOCKET)
  5619.                                         {
  5620.                                                 /* ---------- SOCKCONNECT ---------- */
  5621.                                                 if (!strcasecmp(elts[0].key, "sockconnect"))
  5622.                                                 {
  5623.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "host"))) == NULL) param[0] = "localhost";
  5624.                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag, "service"))) != NULL)
  5625.                                                         {
  5626.                                                                 y = socket_connect(&conf->sock[x], param[0], param[1]);
  5627.  
  5628.                                                                 imprime(conf, "%d", y);
  5629.                                                         }
  5630.                                                 }
  5631.                                                 /* ---------- SOCKHTTP ---------- */
  5632.                                                 else if (!strcasecmp(elts[0].key, "sockhttp"))
  5633.                                                 {
  5634.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "href"))) != NULL)
  5635.                                                         {
  5636.                                                                 ap_parse_uri_components(conf->pool_tag, param[0], &uptr);
  5637.                                                                 if (uptr.is_initialized)
  5638.                                                                 {
  5639.                                                                         if (!uptr.port_str) uptr.port_str = "80";
  5640.                                                                         if (uptr.query) temp = ap_pstrcat(conf->pool_tag, "?", uptr.query, NULL);
  5641.                                                                         else temp = "";
  5642.                
  5643.                                                                         if ((y = socket_connect(&conf->sock[x], uptr.hostname, uptr.port_str)) > 0)
  5644.                                                                         {
  5645.                                                                                 ap_bprintf(conf->sock[x].f, "GET %s%s HTTP/1.0\r\n", uptr.path, temp);
  5646.                                                                                 ap_bprintf(conf->sock[x].f, "Connection: close\r\n");
  5647.                                                                                 ap_bprintf(conf->sock[x].f, "User-Agent: %s/%s [] (%s)\r\n", ADML_NOM, ADML_VERSION, ap_get_server_version());
  5648.                                                                                 ap_bprintf(conf->sock[x].f, "Host: %s\r\n", uptr.hostname);
  5649.                                                                                 if (uptr.user != NULL)  /* USER */
  5650.                                                                                 {
  5651.                                                                                         if ((param[3] = uptr.password) == NULL) param[3] = ""/* PASSWORD */
  5652.                                                                                         temp = ap_psprintf(conf->pool_tag, "%s:%s", uptr.user, param[3]);
  5653.                                                                                         ap_bprintf(conf->sock[x].f, "Authorization: Basic %s\r\n", base64encode(conf->pool_tag, temp, strlen(temp), NULL));
  5654.                                                                                 }
  5655.                                                                                 ap_bprintf(conf->sock[x].f, "\r\n");
  5656.                                                                                 ap_bflush(conf->sock[x].f);     /* vide le tampon */
  5657.                
  5658.                                                                                 z = 0;
  5659.                                                                                 flag = FALSE;
  5660.                                                                                 while((y = socket_readmsg(r, &conf->sock[x], conf->buffer, TAILLE_BUFFER)) > 0)
  5661.                                                                                 {
  5662.                                                                                         if (flag)       /* recuperation des donnees */
  5663.                                                                                         {
  5664.                                                                                                 if ((z + y) >= conf->sock[x].taille_buffer_max) /* Si l'emplacement est trop petit */
  5665.                                                                                                 {
  5666.                                                                                                         conf->sock[x].taille_buffer_max += TAILLE_BUFFER;
  5667.                                                                                                         temp = ap_palloc(conf->sock[x].p, sizeof(char) * (conf->sock[x].taille_buffer_max + 1));
  5668.                                                                                                         memcpy(temp, conf->sock[x].buffer, sizeof(char) * z);
  5669.                                                                                                         conf->sock[x].buffer = temp;
  5670.                                                                                                 }
  5671.  
  5672.                                                                                                 memcpy(&conf->sock[x].buffer[z], conf->buffer, sizeof(char) * y);
  5673.                                                                                                 z += y;
  5674.                                                                                         }
  5675.                                                                                         else    /* On est encore dans l'header */
  5676.                                                                                         {
  5677.                                                                                                 if (!strcmp(conf->buffer, "\n") || !strcmp(conf->buffer, "\r\n")) flag = TRUE/* Afin de sauter l'header */
  5678.                                                                                                 else    /* Recup de l'header */
  5679.                                                                                                 {
  5680.                                                                                                 }
  5681.                                                                                         }
  5682.                                                                                 }
  5683.                                                                                 conf->sock[x].taille_buffer = z;        /* Stock la taille des donnees disponible dans le buffer de la socket */
  5684.                                                                                 conf->sock[x].buffer[z] = 0;    /* fin de chaine */
  5685.                                                                                 socket_close(&conf->sock[x]);    /* Ferme la socket */
  5686.                                                                         }
  5687.                                                                 }
  5688.                                                         }
  5689.                                                         else
  5690.                                                         {
  5691.                                                                 /* WARNING (pas de parametre HREF) */
  5692.                                                         }
  5693.                                                 }
  5694.                                                 /* ---------- SOCKREAD... ---------- */
  5695.                                                 else if (!strncasecmp(elts[0].key, "sockread", 8))
  5696.                                                 {
  5697.                                                         if (i == 1)
  5698.                                                         {
  5699.                                                                 while((y = socket_readmsg(r, &conf->sock[x], conf->buffer, TAILLE_BUFFER)) > 0)
  5700.                                                                 {
  5701.                                                                         imprime(conf, "[%d][%s]", strlen(conf->buffer), conf->buffer);
  5702.                                                                 }
  5703.                                                         }
  5704.                                                         else
  5705.                                                         {
  5706.                                                                 y = socket_readmsg(r, &conf->sock[x], conf->buffer, TAILLE_BUFFER);
  5707. if (y > 0) ap_rprintf(r, " [%s] ", conf->sock[x].buffer);
  5708. else ap_rprintf(r, " ReadSocket=[%d] ", y);
  5709.                                                         }
  5710.                                                 }
  5711.                                                 /* ---------- SOCKREAD... ---------- */
  5712.                                                 else if (!strncasecmp(elts[0].key, "sockread", 8))
  5713.                                                 {
  5714.                                                         socket_read(r, conf->pool_tag, &conf->sock[x]);
  5715.                                                 }
  5716.                                                 /* ---------- SOCKWRITE... ---------- */
  5717.                                                 else if (!strncasecmp(elts[0].key, "sockwrite", 9))
  5718.                                                 {
  5719.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"value"))) != NULL)
  5720.                                                         {
  5721.                                                                 ap_bprintf(conf->sock[x].f, "%s", param[0]);
  5722.                                                                 ap_bflush(conf->sock[x].f);
  5723. /*
  5724.                                                                 y = socket_write(&conf->sock[x], param[0], strlen(param[0]));
  5725. */
  5726.                                                         }
  5727.                                                 }
  5728.                                         }
  5729.                                 }
  5730.                                 /*----------------------------------------------------------------*/
  5731.                                 /* MYSQL...                                                       */
  5732.                                 /*----------------------------------------------------------------*/
  5733.                                 else if (!strncasecmp(elts[0].key,"mysql",5))
  5734.                                 {
  5735.                                         if (strlen(elts[0].val)>0) x = atoi(valeur);    /* Numero de la structure a utiliser */
  5736.                                         else x = conf->mysql_def;       /* Prend le numero de structure par defaut */
  5737.  
  5738.                                         if (x >= 0 && x < N_MYSQL)
  5739.                                         {
  5740.                                                 /* ---------- MYSQLCONNECT ---------- */
  5741.                                                 if (!strcasecmp(elts[0].key, "mysqlconnect") || !conf->base_mysql[x].fconnect)  /* Se connect si commande mysqlConnect ou avec valeur par defaut si pas encore connecte */
  5742.                                                 {
  5743.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"host"))) == NULL) param[0] = conf->mysql_host;
  5744.                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag,"login"))) == NULL) param[1] = conf->mysql_user;    /* Ou User= egalement */
  5745.                                                         if ((param[2] = interp(conf, ap_table_get(conf->tag,"passwd"))) == NULL) param[2] = conf->mysql_passwd; /* ou password= egalement */
  5746.                                                         md_mysql_connect(&conf->base_mysql[x], param[0], param[1], param[2]);
  5747.  
  5748.                                                         if (!conf->base_mysql[x].ferror && strcasecmp(elts[0].key, "mysqlselect"))      /* Si il n'y a pas d'erreur et que la commande n'est pas un mysqlselect, alors peut prendre le parametre optionel 'base' */
  5749.                                                         {
  5750.                                                                 if ((param[3] = interp(conf, ap_table_get(conf->tag,"base"))) == NULL) param[3] = conf->mysql_base;
  5751.                                                                 if (param[3] != NULL) md_mysql_select(&conf->base_mysql[x], param[3]);
  5752.                                                         }
  5753.                                                 }
  5754.  
  5755.                                                 /* ---------- MYSQLCLOSE ---------- */
  5756.                                                 if (!strcasecmp(elts[0].key, "mysqlclose")) md_mysql_close(&conf->base_mysql[x]);
  5757.                                                 /* ------------------------------------------------------------ */
  5758.                                                 /* Si une connection a un serveur existe                        */
  5759.                                                 /* ------------------------------------------------------------ */
  5760.                                                 else if (conf->base_mysql[x].fconnect)
  5761.                                                 {
  5762.                                                         /* ---------- MYSQLSELECT ---------- */
  5763.                                                         if (!strcasecmp(elts[0].key, "mysqlselect"))
  5764.                                                         {
  5765.                                                                 md_mysql_select(&conf->base_mysql[x], interp(conf, ap_table_get(conf->tag, "base")));
  5766.                                                         }
  5767.                                                         /* ---------- MYSQLFREERES... ------- */
  5768.                                                         else if (!strncasecmp(elts[0].key, "mysqlfreeres", 12)) md_mysql_freeresult(&conf->base_mysql[x]);
  5769.                                                         /* ---------- MYSQLRELOAD ------- */
  5770.                                                         else if (!strcasecmp(elts[0].key, "mysqlreload")) md_mysql_reload(&conf->base_mysql[x]);
  5771.                                                         /* ---------- MYSQLSHUTDOWN ------- */
  5772.                                                         else if (!strcasecmp(elts[0].key, "mysqlshutdown")) mysql_shutdown(&conf->base_mysql[x].mysql);
  5773.                                                         /* ---------- MYSQLPROC... ---------- */
  5774.                                                         else if (!strncasecmp(elts[0].key, "mysqlproc", 9)) md_mysql_processes(&conf->base_mysql[x]);
  5775.                                                         /* ---------- MYSQLLISTDB... ---------- */
  5776.                                                         else if (!strncasecmp(elts[0].key, "mysqllistdb", 11))
  5777.                                                         {
  5778.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "wild"))) == NULL) param[0] = "";
  5779.        
  5780.                                                                 md_mysql_listdbs(&conf->base_mysql[x], param[0]);
  5781.                                                         }
  5782.                                                         /* ------------------------------------------------------------ */
  5783.                                                         /* Si une base a ete selectionne                                */
  5784.                                                         /* ------------------------------------------------------------ */
  5785.                                                         else if (conf->base_mysql[x].fbase)
  5786.                                                         {
  5787.                                                                 /* ---------- MYSQLQUERY ---------- */
  5788.                                                                 if (!strcasecmp(elts[0].key, "mysqlquery"))
  5789.                                                                 {
  5790.                                                                         md_mysql_query(&conf->base_mysql[x], interp(conf, ap_table_get(conf->tag, "query")));
  5791.                                                                 }
  5792.                                                                 /* ---------- MYSQLLISTFIELD... ---------- */
  5793.                                                                 else if (!strncasecmp(elts[0].key, "mysqllistfield", 14))
  5794.                                                                 {
  5795.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "table"))) == NULL) param[0] = "";
  5796.                                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag,"wild"))) == NULL) param[1] = "";
  5797.        
  5798.                                                                         md_mysql_listfields(&conf->base_mysql[x], param[0], param[1]);
  5799.                                                                 }
  5800.                                                                 /* ---------- MYSQLLISTTABLE... ---------- */
  5801.                                                                 else if (!strncasecmp(elts[0].key, "mysqllisttable", 14))
  5802.                                                                 {
  5803.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag,"wild"))) == NULL) param[0] = "";
  5804.                                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag,"base"))) != NULL) md_mysql_select(&conf->base_mysql[x], param[1]);
  5805.        
  5806.                                                                         md_mysql_listtables(&conf->base_mysql[x], param[0]);
  5807.                                                                 }
  5808.                                                                 /* ---------- MYSQLBASK... ---------- */
  5809.                                                                 else if (!strncasecmp(elts[0].key, "mysqlbask", 9))
  5810.                                                                 {
  5811.                                                                         for (i = 0; i < 10; i++) num[i] = 0;    /* Initialise toutes les variables a 0 */
  5812.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num0"))) != NULL) num[0] = atoi(param[0]);
  5813.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num1"))) != NULL) num[1] = atoi(param[0]);
  5814.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num2"))) != NULL) num[2] = atoi(param[0]);
  5815.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num3"))) != NULL) num[3] = atoi(param[0]);
  5816.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num4"))) != NULL) num[4] = atoi(param[0]);
  5817.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num5"))) != NULL) num[5] = atoi(param[0]);
  5818.  
  5819.                                                                         if ((param[2] = interp(conf, ap_table_get(conf->tag, "table"))) == NULL) param[2] = "basket";   /* TABLE */
  5820.                                                                         if ((param[4] = interp(conf, ap_table_get(conf->tag, "expire"))) != NULL)       /* EXPIRE () */
  5821.                                                                         {
  5822.                                                                                 i = atoi(param[4]);
  5823.                                                                                 if (i < 1) i = 1;
  5824.                                                                                 temp = ap_psprintf(conf->pool_tag, "DELETE FROM %s WHERE TO_DAYS(NOW())-TO_DAYS(date)>='%d'", param[2], i);     /* supprime les enregistrements qui ont expires du panier */
  5825.                                                                                 if (!md_mysql_query(&conf->base_mysql[x], temp))
  5826.                                                                                 {
  5827.                                                                                         error = "ERREUR Mysql: ...";
  5828.                                                                                 }
  5829.                                                                         }
  5830.  
  5831.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "product"))) != NULL) i = abs(atoi(param[0]));     /* PRODUCT */
  5832.                                                                         else i = 0;
  5833.  
  5834.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "quantity"))) != NULL) w = atoi(param[0])/* QUANTITY */
  5835.                                                                         else w = 1;
  5836.  
  5837.                                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "session"))) != NULL) /* SESSION */
  5838.                                                                         {
  5839.                                                                                 param[1] = interp(conf, ap_table_get(conf->tag, "misc"));       /* MISC */
  5840.                                                                                 if ((param[3] = interp(conf, ap_table_get(conf->tag, "type"))) == NULL) param[3] = "read";      /* TYPE */
  5841.  
  5842.                                                                                 if (!strcasecmp(param[3], "clear"))     /* Type = clear */
  5843.                                                                                 {
  5844.                                                                                         temp = ap_psprintf(conf->pool_tag, "DELETE FROM %s WHERE session='%s'", param[2], param[0]);
  5845.                                                                                         if (!md_mysql_query(&conf->base_mysql[x], temp))
  5846.                                                                                         {
  5847.                                                                                                 error = "ERREUR Mysql: ...";
  5848.                                                                                         }
  5849.                                                                                 }
  5850.                                                                                 else if (strcasecmp(param[3], "read"))  /* Type != read */
  5851.                                                                                 {
  5852.                                                                                         temp = ap_psprintf(conf->pool_tag, "SELECT id,quantity,misc,num0,num1,num2,num3,num4,num5 FROM %s WHERE session='%s' AND product='%d' AND num0='%d' AND num1='%d' AND num2='%d' AND num3='%d' AND num4='%d' AND num5='%d'", param[2], param[0], i, num[0], num[1], num[2], num[3], num[4], num[5]);
  5853.                                                                                         if (md_mysql_query(&conf->base_mysql[x], temp))
  5854.                                                                                         {
  5855.                                                                                                 temp = NULL;
  5856.                                                                                                 if (!strncasecmp(param[3], "add", 3) || !strncasecmp(param[3], "set", 3))       /* Type = add... ou set... */
  5857.                                                                                                 {
  5858.                                                                                                         if (mysql_num_rows(conf->base_mysql[x].res) > 0)        /* S'il y a des enregistrements */
  5859.                                                                                                         {
  5860.                                                                                                                 if (strncasecmp(param[3], "set", 3)) w = atoi(conf->base_mysql[x].row[1]) + w;  /* Ajoute a la quantite */
  5861.        
  5862.                                                                                                                 if (param[1] == NULL) param[1] = "";    /* Pas de chaine Misc */
  5863.                                                                                                                 else param[1] = conf->base_mysql[x].row[2];     /* recupere l'ancienne chaine Misc */
  5864.        
  5865.                                                                                                                 if (w < 1) temp = ap_psprintf(conf->pool_tag, "DELETE FROM %s WHERE id='%d'", param[2], atoi(conf->base_mysql[x].row[0]));      /* supprime l'enregistrement du panier */
  5866.                                                                                                                 else temp = ap_psprintf(conf->pool_tag, "UPDATE %s SET quantity='%d',misc='%s',date=NOW() WHERE id='%d'", param[2], w, param[1], atoi(conf->base_mysql[x].row[0]));     /* Modifie l'enregistrement */
  5867.                                                                                                         }
  5868.                                                                                                         else    /* s'il n'y a pas encore d'enregistrement et que ce n'est pas un type = del */
  5869.                                                                                                         {
  5870.                                                                                                                 temp = ap_psprintf(conf->pool_tag, "INSERT INTO %s (quantity,session,product,misc,date,num0,num1,num2,num3,num4,num5) VALUES ('%d','%s','%d','%s',NOW(),'%d','%d','%d','%d','%d','%d')", param[2], w, param[0], i, param[1], num[0], num[1], num[2], num[3], num[4], num[5]);
  5871.                                                                                                         }
  5872.                                                                                                 }
  5873.                                                                                                 else if (!strncasecmp(param[3], "del", 3))      /* Type = del */
  5874.                                                                                                 {
  5875.                                                                                                         if (mysql_num_rows(conf->base_mysql[x].res) > 0)        /* S'il y a des enregistrements */
  5876.                                                                                                         {
  5877.                                                                                                                 temp = ap_psprintf(conf->pool_tag, "DELETE FROM %s WHERE id='%d'", param[2], atoi(conf->base_mysql[x].row[0]))/* supprime l'enregistrement du panier */
  5878.                                                                                                         }
  5879.                                                                                                 }
  5880.                                                                                                 else
  5881.                                                                                                 {
  5882.                                                                                                         error = "ERREUR Mysql: La valeur du parametre type est incorrect !";
  5883.                                                                                                 }
  5884.  
  5885.                                                                                                 if (temp != NULL)
  5886.                                                                                                 {
  5887.                                                                                                         if (!md_mysql_query(&conf->base_mysql[x], temp))
  5888.                                                                                                         {
  5889.                                                                                                                 error = "ERREUR Mysql: ...";
  5890.                                                                                                         }
  5891.                                                                                                 }
  5892.                                                                                         }
  5893.                                                                                         else    /* ERREUR */
  5894.                                                                                         {
  5895.                                                                                                 error = "ERREUR Mysql: ...";
  5896.                                                                                         }
  5897.                                                                                 }
  5898.  
  5899.                                                                                 if (ap_table_get(conf->tag, "read") != NULL) /* READ */
  5900.                                                                                 {
  5901.                                                                                         if ((temp = interp(conf, ap_table_get(conf->tag, "orderby"))) != NULL)  /* Ordre de tri pour le resultat de la requete */
  5902.                                                                                         {
  5903.                                                                                                 if (!strcasecmp(temp, "id") || !strcasecmp(temp, "product") || !strcasecmp(temp, "date") || !strcasecmp(temp, "quantity")) ap_str_tolower(temp);        /* Convertit en minuscule */
  5904.                                                                                                 else temp = "id";
  5905.                                                                                         }
  5906.                                                                                         else temp = "id";
  5907.  
  5908.                                                                                         if (ap_table_get(conf->tag, "orderdesc") != NULL) valeur = "DESC";      /* Ordre de tri inverse pour le resultat de la requete */
  5909.                                                                                         else valeur = "";
  5910.  
  5911.                                                                                         temp = ap_psprintf(conf->pool_tag, "SELECT * FROM %s WHERE session='%s' ORDER BY %s %s", param[2], param[0], temp, valeur);
  5912.                                                                                         if (!md_mysql_query(&conf->base_mysql[x], temp))
  5913.                                                                                         {
  5914.                                                                                                 error = "ERREUR Mysql: ...";
  5915.                                                                                         }
  5916.                                                                                 }
  5917.                                                                                 else md_mysql_freeresult(&conf->base_mysql[x])/* vide la query eventuek */
  5918.                                                                         }
  5919.                                                                         else
  5920.                                                                         {
  5921.                                                                                 error = "ERREUR : Pas de parametre session ! ";
  5922.                                                                         }
  5923.                                                                 }
  5924.                                                                 /* ------------------------------------------------------------ */
  5925.                                                                 /* Si une requete a ete effectue                                */
  5926.                                                                 /* ------------------------------------------------------------ */
  5927.                                                                 else if (conf->base_mysql[x].fquery)
  5928.                                                                 {
  5929.                                                                         /* ---------- MYSQLDATASEEK ------- */
  5930.                                                                         if (!strcasecmp(elts[0].key, "mysqldataseek"))
  5931.                                                                         {
  5932.                                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "row"))) == NULL) param[0] = "0";
  5933.                                                                                 md_mysql_dataseek(&conf->base_mysql[x], atoi(param[0]));
  5934.                                                                         }
  5935.                                                                         /* ---------- MYSQLFIELDSEEK ------ */
  5936.                                                                         else if (!strcasecmp(elts[0].key, "mysqlfieldseek"))
  5937.                                                                         {
  5938.                                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "field"))) == NULL) param[0] = "0";
  5939.                                                                                 md_mysql_fieldseek(&conf->base_mysql[x], atoi(param[0]));
  5940.                                                                         }
  5941.                                                                         /* ---------- MYSQLOPT... ---------- */
  5942.                                                                         else if (!strncasecmp(elts[0].key, "mysqlopt", 8))
  5943.                                                                         {
  5944.                                                                                 if (if_sortie)
  5945.                                                                                 {
  5946.                                                                                         if ((param[0] = ap_table_get(conf->tag,"value")) == NULL) param[0] = "";
  5947.                                                                                         if ((param[1] = ap_table_get(conf->tag,"text")) == NULL) param[1] = "";
  5948.                                                                                         if ((param[2] = interp(conf, ap_table_get(conf->tag,"selected"))) == NULL) param[2] = "";
  5949.                                                                                         param[3] = ap_table_get(conf->tag,"filter");
  5950.  
  5951.                                                                                         if (conf->base_mysql[x].fquery) /* Si une requete est OK ! */
  5952.                                                                                         {
  5953.                                                                                                 i = -1;
  5954.                                                                                                 while(++i < md_mysql_nbrrows(&conf->base_mysql[x]))
  5955.                                                                                                 {
  5956.                                                                                                         md_mysql_dataseek(&conf->base_mysql[x], i);
  5957.                                                                                                         if (param[3] != NULL) flag = testlog(conf, interp(conf, param[3]));
  5958.                                                                                                         else flag = TRUE;
  5959.  
  5960.                                                                                                         if (flag)       /* Pour le filtre */
  5961.                                                                                                         {
  5962.                                                                                                                 temp = interp(conf, param[0]);
  5963.                                                                                                                 if (!ap_strcmp_match(temp, param[2])) param[6] = "SELECTED ";
  5964.                                                                                                                 else param[6] = "";
  5965.                                                                          imprime(conf, "<OPTION %sVALUE=\"%s\">%s</OPTION>", param[6], temp, interp(conf, param[1]));
  5966.                                                                                                         }
  5967.                                                                                                 }
  5968.                                                                                         }
  5969.                                                                                 }
  5970.                                                                         }
  5971.                                                                 }
  5972.                                                                 else
  5973.                                                                 {
  5974.                                                                         error = "ERREUR Mysql: Aucune requete n'a ete effectue!";
  5975.                                                                 }
  5976.                                                         }
  5977.                                                         else
  5978.                                                         {
  5979.                                                                 error = "ERREUR Mysql: Aucune base n'a ete selectionne!";
  5980.                                                         }
  5981.                                                 }
  5982.                                                 else
  5983.                                                 {
  5984.                                                         error = "ERREUR Mysql: Aucune connection a un serveur n'a ete effectue!";
  5985.                                                 }
  5986.        
  5987.                                                 /* ---------- si erreur ---------- */
  5988.                                                 if (conf->base_mysql[x].ferror && ap_table_get(conf->tag, "nomessage") == NULL && if_sortie)
  5989.                                                 {
  5990.                                       imprime(conf ,"%s", md_mysql_error(&conf->base_mysql[x]));
  5991.                                                 }
  5992.                                         }
  5993.                                 }
  5994.                                 /*----------------------------------------------------------------*/
  5995.                                 /* FILEDEL...                                                     */
  5996.                                 /*----------------------------------------------------------------*/
  5997.                                 else if (!strncasecmp(elts[0].key, "filedel", 7))
  5998.                                 {
  5999.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "dir"))) == NULL) param[0] = "/";
  6000.  
  6001.                                         conf->rr = (request_rec *)ap_sub_req_lookup_uri(param[0], conf->r);
  6002.                                         if (conf->rr->finfo.st_mode)    /* Si le repertoire existe */
  6003.                                         {
  6004.                                                 if ((param[2] = interp(conf, ap_table_get(conf->tag, "file"))) == NULL) param[2] = conf->upload[z].filename;
  6005.                                                 else if (ifvide(param[2]))      /* Erreur : Le nom de fichier est incorrect (vide) */
  6006.                                                 {
  6007.                                                         /* enregistrer l'erreur */
  6008.                                                 }
  6009.                                                 else
  6010.                                                 {
  6011.                                                         if ((temp = strrchr(param[2], '/')) != NULL) param[2] = temp;   /* Interdit les chemin dans le nom de fichier */
  6012.  
  6013.                                                         if (param[2][1] == '/' || conf->rr->filename[strlen(conf->rr->filename) - 1] == '/') temp = "";
  6014.                                                         else temp = "/";
  6015.  
  6016.                                                         param[3] = ap_psprintf(conf->pool_tag, "%s%s%s", conf->rr->filename, temp, param[2]);
  6017.  
  6018.                                                         if (unlink(param[3]))
  6019.                                                         {
  6020.                                                                 /* Erreur: N'arrive pas a supprimer le fichier */
  6021.                                                         }
  6022.                                                 }
  6023.                                         }
  6024.                                         else
  6025.                                         {
  6026.                                                 /* erreur: le repertoire n'existe pas */
  6027.                                         }
  6028.                                 }
  6029.                                 /*----------------------------------------------------------------*/
  6030.                                 /* UPLOAD...                                                      */
  6031.                                 /*----------------------------------------------------------------*/
  6032.                                 else if (!strncasecmp(elts[0].key, "upload", 6))
  6033.                                 {
  6034.                                         /* ---------- UPLOADSAVE ---------- */
  6035.                                         if (!strcasecmp(elts[0].key, "uploadsave"))
  6036.                                         {
  6037.                                                 if ((temp = interp(conf, ap_table_get(conf->tag, "name"))) != NULL)     /* Si le nom du champ a ete precises ! */
  6038.                                                 {
  6039.                                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "num"))) != NULL) x = atoi(param[0]);      /* Numero du champ */
  6040.                                                         else x = 0;
  6041.  
  6042.                                                         z = -1;
  6043.                                                         if (temp[0] != '#')  /* Recherche en nom */
  6044.                                                         {
  6045.                                                                 for(y=0, w=0; y < conf->nupload; y++)
  6046.                                                                 {
  6047.                                                                         if (!ap_strcmp_match(conf->upload[y].name, temp))
  6048.                                                                         {
  6049.                                                                                 if (w++ >= x)   /* Pour le nbr de champ */
  6050.                                                                                 {
  6051.                                                                                         z = y;
  6052.                                                                                         break;
  6053.                                                                                 }
  6054.                                                                         }
  6055.                                                                 }
  6056.                                                         }
  6057.                                                         else if (!strcmp(temp, "#")) /* Position courante */
  6058.                                                         {
  6059.                                                                 if (conf->upload_num >= 0 && conf->upload_num < conf->nupload) z = conf->upload_num;    /* Trouver */
  6060.                                                         }
  6061.                                                         else if (isnum(&temp[1]) && strlen(&temp[1]) > 0) /* Recherche avec le numero du champ */
  6062.                                                         {
  6063.                                                                 i = atoi(&temp[1]);
  6064.                                                                 if (i >= 0 && i < conf->nupload) z = i; /* Trouver */
  6065.                                                         }
  6066.  
  6067.                                                         if (z > -1)     /* si un champ upload a ete trouve */
  6068.                                                         {
  6069.                                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "dir"))) == NULL) param[1] = "/";
  6070.  
  6071.                                                                 flag = TRUE;
  6072.                                                                 conf->rr = (request_rec *)ap_sub_req_lookup_uri(param[1], conf->r);
  6073.                                                                 if (!conf->rr->finfo.st_mode)   /* Si rien n'existe, alors il faut peut etre creer quelque chose */
  6074.                                                                 {
  6075.                                                                         if (ap_table_get(conf->tag, "createdir") != NULL)       /* si l'option CreateDir est presente */
  6076.                                                                         {
  6077.                                                                                 if (mkdir(conf->rr->filename, S_IREAD|S_IWRITE|S_IEXEC))
  6078.                                                                                 {
  6079.                                                                                         /* ERREUR: N'arrive pas a creer le repertoire ! */
  6080.                                                                                         flag = FALSE;
  6081.                                                                                 }
  6082.                                                                         }
  6083.                                                                         else    /* Erreur: le repertoire n'existe pas et pas d'option CreateDir */
  6084.                                                                         {
  6085.                                                                                 /* enregistrer l'erreur  ou Warning (c'est a voir) */
  6086.                                                                                 flag = FALSE;
  6087.                                                                         }
  6088.                                                                 }
  6089.                                                                 else if (!S_ISDIR (conf->rr->finfo.st_mode))    /* Non, ce n'est pas un directory */
  6090.                                                                 {
  6091.                                                                         /* ---------- INSCRIRE L'ERREUR dans la table des erreurs ---------- */
  6092.                                                                         flag = FALSE;   /* Ne plus poursuivre */
  6093.                                                                 }
  6094.  
  6095.                                                                 if (flag)       /* Si l'on peut poursuivre */
  6096.                                                                 {
  6097.                                                                         if ((param[2] = interp(conf, ap_table_get(conf->tag, "file"))) == NULL) param[2] = conf->upload[z].filename;
  6098.                                                                         else if (ifvide(param[2]))      /* Erreur : Le nom de fichier est incorrect (vide) */
  6099.                                                                         {
  6100.                                                                                 /* enregistrer l'erreur */
  6101.                                                                                 flag = FALSE;   /* abandonner l'operation */
  6102.                                                                         }
  6103.  
  6104.                                                                         if (flag)
  6105.                                                                         {
  6106.                                                                                 param[3] = "";
  6107.                                                                                 if (ap_table_get(conf->tag, "ext") != NULL)     /* Si il y a une extension de fichier a ajouter */
  6108.                                                                                 {
  6109.                                                                                         if ((temp = strrchr(conf->upload[z].filename, '.')) != NULL) param[3] = ap_pstrdup(conf->pool_tag, temp);
  6110.                                                                                 }
  6111.  
  6112.                                                                                 if ((temp = strrchr(param[2], '/')) != NULL) param[2] = temp;   /* Interdit les chemin dans le nom de fichier */
  6113.  
  6114.                                                                                 if (param[2][1] == '/' || conf->rr->filename[strlen(conf->rr->filename) - 1] == '/') temp = "";
  6115.                                                                                 else temp = "/";
  6116.  
  6117.                                                                                 param[4] = ap_psprintf(conf->pool_tag, "%s%s%s%s", conf->rr->filename, temp, param[2], param[3]);
  6118.                                                                                 if ((f = fopen(param[4], "w")) != NULL)
  6119.                                                                                 {
  6120.                                                                                         fwrite(conf->upload[z].data, (size_t)conf->upload[z].taille, (size_t)sizeof(char), f);
  6121.                                                                                         conf->upload[z].save = ap_psprintf(conf->pool_session, "%s%s", param[2], param[3]);
  6122.                                                                                         fclose(f);      /* Fermeture du fichier */
  6123.                                                                                 }
  6124.                                                                                 else    /* erreur d'ouverture du fichier en ecriture */
  6125.                                                                                 {
  6126.                                                                                         /* enregistrer l'erreur */
  6127.                                                                                 }
  6128.                                                                         }
  6129.                                                                 }
  6130.                                                         }
  6131.                                                 }
  6132.                                                 else
  6133.                                                 {
  6134.                                                         /* WARNING : Pas de parametre name ! --------------- */
  6135.                                                 }
  6136.                                         }
  6137.                                 }
  6138. #if _XML_EXPAT > 0
  6139.                                 /*----------------------------------------------------------------*/
  6140.                                 /* XML...                                                         */
  6141.                                 /*----------------------------------------------------------------*/
  6142.                                 else if (!strncasecmp(elts[0].key, "xml",3))
  6143.                                 {
  6144.                                         x = atoi(valeur);       // Numero de la structure a utiliser
  6145.  
  6146.                                         if (x >= 0 && x < N_XML)
  6147.                                         {
  6148.                                                 /* ---------- XMLCREAT... ------- */
  6149.                                                 if (!strncasecmp(elts[0].key, "xmlcreat", 8))
  6150.                                                 {
  6151.                                                         conf->xml[x].parser = XML_ParserCreate(NULL);   /* creation */
  6152.                                                 }
  6153.                                                 /* ---------- XMLFREE... ------- */
  6154.                                                 else if (!strncasecmp(elts[0].key, "xmlfree", 7)) XML_ParserFree(conf->xml[x].parser);
  6155.                                         }
  6156.  
  6157.                                 }
  6158. #endif
  6159.                                 /*----------------------------------------------------------------*/
  6160.                                 /* ENV...                                                         */
  6161.                                 /*----------------------------------------------------------------*/
  6162.                                 else if (!strncasecmp(elts[0].key, "env",3))
  6163.                                 {
  6164.                                         if ((param[0] = interp(conf, ap_table_get(conf->tag, "name"))) == NULL) param[0] = valeur;      /* Recupere le nom de la variable d'environement */
  6165.  
  6166.                                         if (!ifvide(param[0]))
  6167.                                         {
  6168.                                                 if ((param[1] = interp(conf, ap_table_get(conf->tag, "value"))) == NULL) param[1] = ""/* Recupere la valeur de la variable d'environement */
  6169.  
  6170.                                                 /* ---------- ENVADD... ---------- */
  6171.                                                 if (!strncasecmp(elts[0].key,"envadd",6)) ap_table_set(r->subprocess_env, param[0], param[1]);
  6172.                                                 /* ---------- ENVSUP... ---------- */
  6173.                                                 else if (!strncasecmp(elts[0].key, "envdel",6)) ap_table_unset(r->subprocess_env, param[0]);
  6174.                                         }
  6175.                                 }
  6176.                                 /*----------------------------------------------------------------*/
  6177.                                 /* TPE...                                                         */
  6178.                                 /*----------------------------------------------------------------*/
  6179.                                 else if (!strncasecmp(elts[0].key, "tpe",3))
  6180.                                 {
  6181.                                         /*----------------------------------------------------------------*/
  6182.                                         /* TPECMFORM...                                                   */
  6183.                                         /*----------------------------------------------------------------*/
  6184.                                         if (!strncasecmp(elts[0].key, "tpecmform", 9))
  6185.                                         {
  6186. #if _TPE_CM > 0  /* TPE du Credit Mutuel */
  6187.                                                 if ((temp = interp(conf, ap_table_get(conf->tag, "text"))) == NULL) temp = ""/* texte libre */
  6188.                                                 valeur = ap_uuencode(conf->pool_tag, temp);
  6189.                                                 if (strlen(valeur) > 3200) valeur[3200] = 0;    /* Limite la taille de la chaine a 3200 caracteres */
  6190.  
  6191.                                                 if ((temp = interp(conf, ap_table_get(conf->tag, "amount"))) != NULL)   /* Montant de la commnande */
  6192.                                                 {
  6193.                                                         if ((conf->temp = strchr(temp, ',')) != NULL) conf->temp[0] = '.';      /* remplace la virgule par un point */
  6194.                                                         if (isnum(temp))        /* verifie si c'est bien une valeur numerique */
  6195.                                                         {
  6196.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "currency"))) != NULL) temp = ap_pstrcat(conf->pool_tag,temp,param[0],NULL);       /* code de la devise */
  6197.  
  6198.                                                                 if ((param[0] = interp(conf, ap_table_get(conf->tag, "tpe"))) != NULL)
  6199.                                                                 {
  6200.                                                                         if ((param[1] = interp(conf, ap_table_get(conf->tag, "code"))) != NULL)
  6201.                                                                         {
  6202.                                                                                 if ((param[2] = interp(conf, ap_table_get(conf->tag, "ref"))) == NULL) param[2] = "";   /* Reference de la commande */
  6203.                                                                                 if ((param[3] = interp(conf, ap_table_get(conf->tag, "urlret"))) == NULL) param[3] = "";        /* URL de retour */
  6204.                                                                                 if ((param[4] = interp(conf, ap_table_get(conf->tag, "urlok"))) == NULL) param[4] = ""/* URL de retour si paiement OK */
  6205.                                                                                 if ((param[5] = interp(conf, ap_table_get(conf->tag, "urlerr"))) == NULL) param[5] = "";        /* URL de retour si paiement error */
  6206.                                                                                 if ((param[6] = interp(conf, ap_table_get(conf->tag, "textbutton"))) == NULL) param[6] = "";    /* Texte du bouton */
  6207.                                                                                 if ((param[7] = interp(conf, ap_table_get(conf->tag, "action"))) == NULL) param[7] = "";        /* URL pour la requete du formulaire */
  6208.                                                                                 if ((param[8] = interp(conf, ap_table_get(conf->tag, "version"))) == NULL) param[8] = "1.2";    /* Version du systeme de paiement de la banque */
  6209.                                                                                 if ((param[9] = interp(conf, ap_table_get(conf->tag, "language"))) == NULL) param[9] = "francais";      /* la langue (francais par defaut) */
  6210.  
  6211.                                                                                 conf->temp = ap_palloc(conf->pool_tag, 8000 * sizeof(char));    /* Prevoie assez de place pour qu'il n'y est pas de debordement */
  6212.                                                                                 CreerFormulaireCM(param[7], param[8], param[0], temp, param[2], valeur, param[3], param[4], param[5], param[9], param[1], param[6], conf->temp);
  6213.                                                                                 imprime(conf, "%s", conf->temp);                /* sortie de l'erreur a l'ecran */
  6214.                                                                         }
  6215.                                                                         else
  6216.                                                                         {
  6217.                                                                                 error = "Le parametre code est manquant !";     /* erreur */
  6218.                                                                         }
  6219.                                                                 }
  6220.                                                                 else
  6221.                                                                 {
  6222.                                                                         error = "Le parametre tpe est manquant !";      /* erreur */
  6223.                                                                 }
  6224.                                                         }
  6225.                                                         else
  6226.                                                         {
  6227.                                                                 error = "Le parametre amount ne contient pas une valeur numerique !";   /* Erreur */
  6228.                                                         }
  6229.                                                 }
  6230.                                                 else
  6231.                                                 {
  6232.                                                         error = "Parametre amount manquant !"/* Erreur */
  6233.                                                 }
  6234. #else
  6235.                                                 /* WARNING (option non implemente) <---------------------- */
  6236.                                                 error = "Cette Option n'est pas implemente !";
  6237. #endif
  6238.                                                 if (error)
  6239.                                                 {
  6240.                                                         imprime(conf, "%s", error);          /* sortie de l'erreur a l'ecran */
  6241.                                                 }
  6242.                                         }
  6243.                                 }
  6244.                                 /*----------------------------------------------------------------*/
  6245.                                 /* TAG INCONNU                                                    */
  6246.                                 /*----------------------------------------------------------------*/
  6247.                                 else
  6248.                                 {
  6249.                                         imprime(conf, " TAG_INCONNU=[%s] ", elts[0].key);
  6250.                                 }
  6251.                         }
  6252.                 }
  6253.         }
  6254.         /*----------------------------------------------------------------*/
  6255.         /* TAG VIDE                                                       */
  6256.         /*----------------------------------------------------------------*/
  6257.         else
  6258.         {
  6259.                 imprime(conf, "%s", "TAG_VIDE");
  6260.         }
  6261.  
  6262. }
  6263.  
  6264. /*--------------------------------------------------------------------------*/
  6265. /* Analyse page */
  6266. /*--------------------------------------------------------------------------*/
  6267. static void analyse_page(request_rec *r, char *fichier)
  6268. {
  6269.         adml_cfg *conf;
  6270.         int guil, chval, enr, bksl, brk, pos, ncar;
  6271.         char *nom, *valeur;
  6272.  
  6273.         conf = (adml_cfg *) ap_get_module_config(r->per_dir_config, &adml_module);      /* recupere la config */
  6274.         conf->ligne = 1;        /* Positionne le numero de ligne courante sur la premiere ligne (utile pour les erreurs) */
  6275.  
  6276.         /* ----------------------------------------------------------------- */
  6277.         for (conf->pos_fichier=0; conf->pos_fichier < conf->taille_fichier && fichier[conf->pos_fichier] != '\0'; conf->pos_fichier++)
  6278.         {
  6279.                 if (fichier[conf->pos_fichier] == '\n') conf->ligne++;  /* Incremente le numero de la ligne */
  6280.  
  6281.                 if (!strncmp(&fichier[conf->pos_fichier],DEBUT_TAG,2))
  6282.                 {
  6283.                         conf->debut_tag = conf->pos_fichier;    /* Enregistre la position du premier caractere du tag (pour l'include) */
  6284.                         ap_clear_pool(conf->pool_tag)/* Detruit le contenu du pool */
  6285.                         conf->tag = ap_make_table(conf->pool_tag,1);    /* Cree la table pour les parametres de tag */
  6286.  
  6287.                         guil = chval = enr = bksl = ncar = brk = FALSE;
  6288.                         nom = valeur = NULL;
  6289.                         pos = ++conf->pos_fichier +1;
  6290.                         while(++conf->pos_fichier < conf->taille_fichier)
  6291.                         {
  6292.                                 if (!strncmp(&fichier[conf->pos_fichier],FIN_TAG,2))
  6293.                                 {
  6294.                                         conf->fin_tag = conf->pos_fichier+1;    /* Enregistre la position du dernier caractere du tag */
  6295.                                         if (conf->notagbr && (fichier[conf->pos_fichier+2] == '\r' || fichier[conf->pos_fichier+2] == '\n'))
  6296.                                         {
  6297.                                                 if (fichier[conf->pos_fichier+2] == '\n') conf->ligne++;        /* Incremente le numero de la ligne */
  6298.                                                 conf->pos_fichier++;
  6299.                                                 if (fichier[conf->pos_fichier+2] == '\n')
  6300.                                                 {
  6301.                                                         conf->ligne++;  /* Incremente le numero de ligne */
  6302.                                                         conf->pos_fichier++;
  6303.                                                 }
  6304.                                         }
  6305.                                         brk = TRUE;
  6306.                                 }
  6307.  
  6308.                                 if (!brk)
  6309.                                 {
  6310.                                         if (guil)
  6311.                                         {
  6312.                                                 if (fichier[conf->pos_fichier] == '\"' && fichier[conf->pos_fichier-1] != '\\')
  6313.                                                 {
  6314.                                                         enr = TRUE;
  6315.                                                         guil = FALSE;
  6316.                                                 }
  6317.                                                 else
  6318.                                                 {
  6319.                                                         if (fichier[conf->pos_fichier] == '\0') enr = TRUE;
  6320.                                                         if (fichier[conf->pos_fichier] == '\\') bksl = TRUE;
  6321.                                                         ncar++;
  6322.                                                 }
  6323.                                         }
  6324.                                         else
  6325.                                         {
  6326.                                                 if (fichier[conf->pos_fichier] == '\"' && fichier[conf->pos_fichier-1] != '\\')
  6327.                                                 {
  6328.                                                         guil = TRUE;
  6329.                                                         if (ncar > 0) enr = TRUE;
  6330.                                                         else pos = conf->pos_fichier+1;
  6331.                                                 }
  6332.                                                 else if (fichier[conf->pos_fichier] == '=' || fichier[conf->pos_fichier] <= 32)
  6333.                                                 {
  6334.                                                         if (ncar > 0) enr = TRUE;
  6335.                                                         else if (fichier[conf->pos_fichier] == '=') chval = TRUE;       /* Dans le cas d'une valeur sans nom */
  6336.                                                 }
  6337.                                                 else
  6338.                                                 {
  6339.                                                         if (fichier[conf->pos_fichier] == '\\') bksl = TRUE;
  6340.                                                         if (ncar++ == 0) pos = conf->pos_fichier;
  6341.                                                 }
  6342.                                         }
  6343.                                 }
  6344.  
  6345.                                 if (enr || (brk && ncar > 0))
  6346.                                 {
  6347.                                         if (chval)
  6348.                                         {
  6349.                                                 if (nom == NULL) nom = "";
  6350.                                                 valeur = ap_pstrndup(conf->pool_tag, &fichier[pos],ncar);
  6351.                                                 if (bksl)
  6352.                                                 {
  6353.                                                         ap_table_addn(conf->tag, unescape_backslash(nom), unescape_backslash(valeur))/* Ajoute nom/valeur dans la table sans duplication (avec un traitement pour les anti-slash) */
  6354.                                                         bksl = FALSE;
  6355.                                                 }
  6356.                                                 else ap_table_addn(conf->tag, nom, valeur);     /* Ajoute nom/valeur dans la table sans duplication */
  6357.                                                 nom = NULL;
  6358.                                                 chval = FALSE;
  6359.                                         }
  6360.                                         else
  6361.                                         {
  6362.                                                 if (nom != NULL)
  6363.                                                 {
  6364.                                                         if (valeur == NULL) valeur = "";
  6365.                                                         if (bksl)
  6366.                                                         {
  6367.                                                                 ap_table_addn(conf->tag, unescape_backslash(nom), unescape_backslash(valeur))/* Ajoute nom/valeur dans la table sans duplication (avec un traitement pour les anti-slash) */
  6368.                                                                 bksl = FALSE;
  6369.                                                         }
  6370.                                                         else ap_table_addn(conf->tag, nom, valeur);     /* Ajoute nom/valeur dans la table sans duplication */
  6371.                                                 }
  6372.                                                 nom = ap_pstrndup(conf->pool_tag, &fichier[pos],ncar);
  6373.                                                 if (fichier[conf->pos_fichier] == '=') chval = TRUE;
  6374.                                         }
  6375.                                         valeur = NULL;
  6376.  
  6377.                                         enr = FALSE;
  6378.                                         pos = conf->pos_fichier+1;
  6379.                                         ncar = 0;
  6380.                                 }
  6381.  
  6382.                                 if (brk)
  6383.                                 {
  6384.                                         if (nom != NULL || valeur != NULL)
  6385.                                         {
  6386.                                                 if (nom == NULL) nom = "";
  6387.                                                 if (valeur == NULL) valeur = "";
  6388.                                                 if (bksl) ap_table_addn(conf->tag, unescape_backslash(nom), unescape_backslash(valeur));        /* Ajoute nom/valeur dans la table sans duplication (avec un traitement pour les anti-slash) */
  6389.                                                 else ap_table_addn(conf->tag, nom, valeur);     /* Ajoute nom/valeur dans la table sans duplication */
  6390.                                         }
  6391.                                         conf->pos_fichier++;
  6392.                                         break;
  6393.                                 }
  6394.                         }
  6395.                         interprete_tag(r);      /* Lance l'interpretation et l'execution du tag */
  6396.                         if (conf->exit) return/* Si exit = TRUE, alors il faut tout arreter */
  6397.                 }
  6398.                 else
  6399.                 {
  6400.                         imprime_char(conf, fichier[conf->pos_fichier])/* Envoi vers le client seulement si la sortie est autorise */
  6401.                 }
  6402.         }
  6403.         /* ----------------------------------------------------------------- */
  6404. }
  6405.  
  6406. /*--------------------------------------------------------------------------*/
  6407. /* Ajoute un element dans une structure Form                                */
  6408. /* Type = 0:Upload ; 1:Add ; 2:array; 4:Ifexist 8:Init                      */
  6409. /* Si copie = TRUE, alors c'est une copie des chaines qui est faite         */
  6410. /*--------------------------------------------------------------------------*/
  6411. static int add_form(table *form, const char *nom, const char *valeur, int type)
  6412. {
  6413.         char *temp;
  6414.         int x;
  6415.         array_header *arr;
  6416.         table_entry *elts;
  6417.  
  6418.         if (nom == NULL) return(FALSE)/* Pas d'ajout */
  6419.  
  6420.         if (type&8)     /* Parametre TYPE=INIT... */
  6421.         {
  6422.                 ap_clear_table(form);   /* Efface la structure Form */
  6423.         }
  6424.  
  6425.         arr = ap_table_elts(form);
  6426.         elts = (table_entry *) arr->elts;
  6427.  
  6428.         if (type&1) ap_table_add(form, nom, valeur);    /* Ajoute un element meme s'il y en a un qui existe deja */
  6429.         else if (type&2) adml_table_merge(form, nom, valeur, FALSE);    /* Ajoute un element en mettant dans le meme champ s'il existe et en separant par une vigule ou un espace */
  6430.         else if (type&4)        /* Remplace un champ existant, mais seulement si le champ existe deja */
  6431.         {
  6432.                 temp = NULL;
  6433.                 for(x=0; x < arr->nelts; x++)
  6434.                 {
  6435.                         if (!strcmp(elts[x].key, nom))
  6436.                         {
  6437.                                 temp = elts[x].val;
  6438.                                 break;
  6439.                         }
  6440.                 }
  6441.                 if (temp != NULL) adml_table_set(form, nom, valeur, FALSE);     /* Ajoute un element en remplacant l'ancien s'il existait */
  6442.                 else return(FALSE);     /* Pas d'ajout */
  6443.         }
  6444.         else adml_table_set(form, nom, valeur, FALSE)/* Ajoute un element en remplacant l'ancien s'il existait */
  6445.  
  6446.         return(TRUE);   /* L'ajout a ete fait */
  6447. }
  6448.  
  6449. /*--------------------------------------------------------------------------*/
  6450. /* Decodage URL_ENCODED Classique                                           */
  6451. /* Si copie = TRUE alors fait une copie de chaine                           */
  6452. /* num est le numero de structure Form dans laquelle enregistrer            */
  6453. /*--------------------------------------------------------------------------*/
  6454. static void decode_classique(adml_cfg *conf, int num, char *chaine, int type, int copie)
  6455. {
  6456.         char *pp, *nom, *val;
  6457.         register int x = 0;
  6458.         register char digit;
  6459.  
  6460.         if (num >= N_FORM) num = 0;     /* verifie que le numero de structure soit correct */
  6461.  
  6462.         if (chaine != NULL)
  6463.         {
  6464.                 if (copie) conf->temp = ap_pstrdup(conf->pool_tag, chaine);     /* Duplique la chaine afin de travailler dessus */
  6465.                 else conf->temp = chaine;       /* Ne duplique pas la chaine. Travail directement dessus */
  6466.  
  6467.                 nom = pp = conf->temp;  /* Pointe au debut de la chaine */
  6468.                 while(*pp != '\0')
  6469.                 {
  6470.                         switch(*pp)
  6471.                         {
  6472.                         case '=':
  6473.                                         conf->temp[x] = '\0';
  6474.                                         val = &conf->temp[x+1];
  6475.                                         break;
  6476.                         case '&':
  6477.                                         conf->temp[x] = '\0';
  6478.                                         add_form(conf->form[num].tab, nom, val, type)/* Ajout du champ */
  6479.                                         nom = &conf->temp[x+1];
  6480.                                         break;
  6481.                         case '+':
  6482.                                         conf->temp[x] = ' ';
  6483.                                         break;
  6484.                         case '%':
  6485.                                         pp++;
  6486.                                         digit = (*pp >= 'A' ? ((*pp & 0xdf) - 'A')+10 : (*pp - '0'));
  6487.                                         pp++;
  6488.                                         digit *= 16;
  6489.                                         digit += (*pp >= 'A' ? ((*pp & 0xdf) - 'A')+10 : (*pp - '0'));
  6490.                                         conf->temp[x] = digit;
  6491.                                         break;
  6492.                         default:
  6493.                                         conf->temp[x] = *pp;
  6494.                         }
  6495.                         pp++;
  6496.                         x++;
  6497.                 }
  6498.                 conf->temp[x] = '\0';
  6499.                 add_form(conf->form[num].tab, nom, val, type)/* Ajout du champ */
  6500.         }
  6501. }
  6502.  
  6503. /*---------------------------------------------------------------------------*/
  6504. /* Decodage MIME                                                             */
  6505. /* Retourne la position dans le buffer si un champ est a recuperer           */
  6506. /* Retourne FALSE si il n'y a plus de champ a recuperer ou si Erreur         */
  6507. /*---------------------------------------------------------------------------*/
  6508. static int decode_mime(adml_mime *mime)
  6509. {
  6510.         int lbound;
  6511.         int encour = FALSE, data = FALSE;
  6512.         char *ptr;
  6513.  
  6514.         mime->fin = FALSE;
  6515.         mime->content_type = mime->content_disposition = mime->content_transfer_encoding = mime->data = "";
  6516.         if (mime->position < 0 || mime->position >= mime->taille) return(FALSE);                        /* Position en dehors de la taille du buffer */
  6517.         if ((lbound = strlen(mime->boundary)) < 1) return(FALSE);                                                 /* erreur de boundary */
  6518.  
  6519.         do
  6520.         {
  6521.                 if (mime->buffer[mime->position] == '-' && mime->buffer[mime->position + 1] == '-')
  6522.                 {
  6523.                         if (!strncmp(&mime->buffer[mime->position + 2], mime->boundary, lbound))
  6524.                         {
  6525.                                 if (!encour)
  6526.                                 {
  6527.                                         mime->position += lbound + 1;
  6528.                                         encour = TRUE;
  6529.                                 }
  6530.                                 else
  6531.                                 {
  6532.                                         if (!strncmp(&mime->buffer[mime->position + lbound + 2], "--", 2)) mime->fin = TRUE;    /* Ont a trouve le boundary de fin */
  6533.  
  6534.                                         if (data)
  6535.                                         {
  6536.                                                 if (mime->buffer[mime->position - 1] == '\n' && mime->buffer[mime->position - 2] == '\r') lbound = 2;
  6537.                                                 else lbound = 1;
  6538.  
  6539.                                                 if (mime->data < (&mime->buffer[mime->position] - lbound)) mime->taille_data = (&mime->buffer[mime->position] - lbound) - mime->data;
  6540.                                                 else mime->taille_data = 0;     /* Pas de donnees */
  6541.                                                 mime->buffer[mime->position - lbound] = '\0';
  6542.                                                 return(TRUE);
  6543.                                         }
  6544.                                         else return(FALSE);
  6545.                                 }
  6546.                         }
  6547.                 }
  6548.                 else if (encour && !data && (mime->buffer[mime->position] == '\n' || (mime->buffer[mime->position] == '\r' && mime->buffer[mime->position + 1] == '\n')))
  6549.                 {
  6550.                         if (mime->buffer[mime->position] == '\r' && mime->buffer[mime->position + 1] == '\n')
  6551.                         {
  6552.                                 mime->buffer[mime->position] = '\0';
  6553.                                 mime->position += 2;
  6554.                         }
  6555.                         else mime->position++;
  6556.  
  6557.                         if (!strncasecmp(&mime->buffer[mime->position], "Content-Type:", 13)) mime->content_type = &mime->buffer[mime->position + 13];
  6558.                         else if (!strncasecmp(&mime->buffer[mime->position], "Content-Disposition:", 20)) mime->content_disposition = &mime->buffer[mime->position + 20];
  6559.                         else if (!strncasecmp(&mime->buffer[mime->position], "Content-Transfer-Encoding:", 26)) mime->content_transfer_encoding = &mime->buffer[mime->position + 26];
  6560.  
  6561.                         if (mime->buffer[mime->position] == '\n' || (mime->buffer[mime->position] == '\r' && mime->buffer[mime->position + 1] == '\n'))
  6562.                         {
  6563.                                 mime->position++;
  6564.                                 if (mime->buffer[mime->position] == '\r' && mime->buffer[mime->position + 1] == '\n') mime->position++;
  6565.                                 data = TRUE;
  6566.                                 mime->data = &mime->buffer[mime->position + 1];
  6567.                         }
  6568.                 }
  6569.         }
  6570.         while(++mime->position < mime->taille);
  6571.  
  6572.         return(FALSE);
  6573. }
  6574.  
  6575. /*--------------------------------------------------------------------------*/
  6576. /* Recupere un element du type name="valeur" dans une chaine                */
  6577. /* Retourne la valeur                                                       */
  6578. /*--------------------------------------------------------------------------*/
  6579. static char *recup_name(pool *p, const char *chaine, const char *name)
  6580. {
  6581.         const char *temp, *valeur;
  6582.         int chaine_len, name_len, i;
  6583.  
  6584.         if (!chaine || !name) return(NULL);
  6585.  
  6586.         chaine_len = strlen(chaine);
  6587.         name_len = strlen(name);
  6588.  
  6589.         for (i = 0; i < chaine_len; i++)
  6590.         {
  6591.                 if (!strncasecmp(&chaine[i], name, name_len))
  6592.                 {
  6593.                         if (!strncmp(&chaine[i + name_len], "=\"", 2))
  6594.                         {
  6595.                                 valeur = &chaine[i + name_len + 2];     /* Debut de la valeur */
  6596.                                 if ((temp = strchr(valeur, '\"')))
  6597.                                 {
  6598.                                         return(ap_pstrndup(p, valeur, temp - valeur));
  6599.                                 }
  6600.                         }
  6601.                 }
  6602.         }
  6603.  
  6604.         return(NULL);
  6605. }
  6606.  
  6607. /*--------------------------------------------------------------------------*/
  6608. /* Decodage multipart/form-data                                             */
  6609. /*--------------------------------------------------------------------------*/
  6610. static int decode_multipart(adml_cfg *conf, int num, char *buffer, unsigned long int taille, int type)
  6611. {
  6612.         adml_mime *mime;
  6613.  
  6614.         mime = ap_palloc(conf->pool_tag, sizeof(adml_mime));
  6615.         mime->buffer = buffer;
  6616.         mime->taille = taille;
  6617.         mime->boundary = conf->boundary;
  6618.         mime->position = 0;
  6619.  
  6620.         while(decode_mime(mime))
  6621.         {
  6622.  
  6623.                 if (!(conf->temp = recup_name(conf->pool_session, mime->content_disposition, " name"))) conf->temp = "";
  6624.                 if ((conf->temp1 = recup_name(conf->pool_session, mime->content_disposition, " filename")))     /* Si c'est un fichier en Upload */
  6625.                 {
  6626.                         if (conf->nupload < N_UPLOAD)
  6627.                         {
  6628.                                 if (mime->taille_data > 0)      /* Si il y a au moins 1 octet */
  6629.                                 {
  6630.                                         conf->upload[conf->nupload].save = NULL;
  6631.                                         conf->upload[conf->nupload].name = conf->temp;
  6632.                                         conf->upload[conf->nupload].data = mime->data;
  6633.                                         conf->upload[conf->nupload].taille = mime->taille_data;
  6634.                                         conf->upload[conf->nupload].content_type = trim(mime->content_type, ' ');
  6635.                                         conf->upload[conf->nupload].remote_filename = conf->temp1;
  6636.                                         if (!(conf->upload[conf->nupload].filename = strrchr(conf->temp1, '\\')))       /* Si c'est un fichier provenant d'un MS-Windows */
  6637.                                         {
  6638.                                                 if (!(conf->upload[conf->nupload].filename = strrchr(conf->temp1, '/'))) conf->upload[conf->nupload].filename = conf->temp1;    /* Si c'est un fichier provenant d'un Unix */
  6639.                                                 else conf->upload[conf->nupload].filename++;
  6640.                                         }
  6641.                                         else conf->upload[conf->nupload].filename++;
  6642.  
  6643.                                         conf->nupload++;
  6644.                                 }
  6645.                         }
  6646.                         else
  6647.                         {
  6648.                                 /* ERREUR : Trop de upload (depasse le nombre maximum autorise */
  6649.                         }
  6650.                 }
  6651.                 else add_form(conf->form[num].tab, conf->temp, mime->data, type);       /* Ajout du champ */ /* Si c'est un champ ordinaire */
  6652.  
  6653.         }
  6654. }
  6655.  
  6656. /*--------------------------------------------------------------------------*/
  6657. /* Recuperation des Cookies de l'entete de la requete                       */
  6658. /*--------------------------------------------------------------------------*/
  6659. static void recup_cookies(adml_cfg *conf)
  6660. {
  6661.         const char *cookies;
  6662.         char *ptr, *ptr1;
  6663.  
  6664.         if ((cookies = ap_pstrdup(conf->pool_tag, ap_table_get(conf->r->headers_in, "Cookie"))))
  6665.         {
  6666.                 while(cookies[0])
  6667.                 {
  6668.                         if (cookies[0] == ',' || cookies[0] == ';') ++cookies;  /* Saute le ; */
  6669.                         ptr = ap_get_token(conf->pool_session, &cookies, 1);
  6670.                         if ((ptr1 = strchr(ptr, '=')) != NULL)
  6671.                         {
  6672.                                 ptr1[0] = 0;    /* Fin de chaine pour separer le nom de la valeur */
  6673.                                 ptr1++;
  6674.                         }
  6675.                         else ptr1 = "";
  6676.  
  6677.                         ap_table_setn(conf->cookies.tab, ptr, ptr1);    /* enregistre le cookie dans la table des cookies (sans duplication) */
  6678.                 }
  6679.         }
  6680.  
  6681. }
  6682.  
  6683. /*--------------------------------------------------------------------------*/
  6684. /* Recuperation des donnees en GET ou POST (et ENCTYPE=multipart/form-data) */
  6685. /*--------------------------------------------------------------------------*/
  6686. static int recup(request_rec *r)
  6687. {
  6688.         adml_cfg *conf;
  6689.         int result = OK;
  6690.         unsigned long int taille = 0, pos = 0, len = 0;
  6691.         char *buffer;
  6692.         const char *temp;
  6693.  
  6694.         conf = (adml_cfg *) ap_get_module_config(r->per_dir_config, &adml_module);      /* recupere la config */
  6695.  
  6696.         if (r->method_number == M_GET)
  6697.         {
  6698.                 decode_classique(conf, 0, r->args, 1, TRUE);    /* Decode la chaine en faisant une copie */
  6699.         }
  6700.         else if (r->method_number == M_POST)
  6701.         {
  6702.                 if ((temp = ap_table_get(r->headers_in, "Content-length")) != NULL) taille = strtol(temp, NULL, 10);
  6703.                 else taille = 0;
  6704.  
  6705.                 if ((temp = ap_table_get(r->headers_in, "Content-type")) != NULL && taille > 0)
  6706.                 {
  6707.                         if (!strncasecmp(temp, "application/x-www-form-urlencoded",33))
  6708.                         {
  6709.                                 if ((result = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) == OK)
  6710.                                 {
  6711.                                         if (ap_should_client_block(r))
  6712.                                         {
  6713.                                                 buffer = ap_pcalloc(conf->pool_tag, taille+1);
  6714.                                                 while ((len = ap_get_client_block(r, &buffer[pos], taille - pos)) > 0) pos += len;      /* Recupere tout en memoire */
  6715.                                                 if (pos > 0) decode_classique(conf, 0, buffer, 1, FALSE);       /* Decode la chaine sans faire de copie */
  6716.                                                 if (len < 0)
  6717.                                                 {
  6718.                                                         /* ---------- Erreur de recuperation !!! ---------- */
  6719.                                                 }
  6720.                                         }
  6721.                                 }
  6722.                         }
  6723.                         else if (!strncasecmp(temp, "multipart/form-data",19) && taille > 0)
  6724.                         {
  6725.                                 if ((result = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) == OK)
  6726.                                 {
  6727.                                         if (ap_should_client_block(r))
  6728.                                         {
  6729.                                                 buffer = ap_pcalloc(conf->pool_session, taille+1);
  6730.                                                 while ((len = ap_get_client_block(r, &buffer[pos], taille - pos)) > 0) pos += len;
  6731.                                                 if (pos > 0) decode_multipart(conf, 0, buffer, pos, 1)/* Decode la chaine */
  6732.                                                 if (len < 0)
  6733.                                                 {
  6734.                                                         /* ---------- Erreur de recuperation !!! ---------- */
  6735.                                                 }
  6736.                                         }
  6737.                                 }
  6738.                         }
  6739.                 }
  6740.         }
  6741.  
  6742.         return(0);
  6743. }
  6744.  
  6745. /*--------------------------------------------------------------------------*/
  6746. /* Ajout de differentes variables d'environnements                          */
  6747. /*--------------------------------------------------------------------------*/
  6748. static void add_vars(request_rec *r)
  6749. {
  6750. #ifndef WIN32
  6751.     struct passwd *pw;
  6752. #endif /* ndef WIN32 */
  6753.     char *t;
  6754.  
  6755.     ap_table_setn(r->subprocess_env, "DATE_LOCAL", ap_ht_time(r->pool, r->request_time, FORMAT_DATE_DEFAUT, 0));
  6756.     ap_table_setn(r->subprocess_env, "DATE_GMT", ap_ht_time(r->pool, r->request_time, FORMAT_DATE_DEFAUT, 1));
  6757.     ap_table_setn(r->subprocess_env, "LAST_MODIFIED", ap_ht_time(r->pool, r->finfo.st_mtime, FORMAT_DATE_DEFAUT, 0));
  6758.     ap_table_setn(r->subprocess_env, "DOCUMENT_URI", r->uri);
  6759.     ap_table_setn(r->subprocess_env, "DOCUMENT_PATH_INFO", r->path_info);
  6760. #ifndef WIN32
  6761.     pw = getpwuid(r->finfo.st_uid);
  6762.     if (pw) ap_table_setn(r->subprocess_env, "USER_NAME", ap_pstrdup(r->pool, pw->pw_name));
  6763.     else ap_table_setn(r->subprocess_env, "USER_NAME", ap_psprintf(r->pool, "user#%lu", (unsigned long) r->finfo.st_uid));
  6764. #endif /* ndef WIN32 */
  6765.  
  6766.     if ((t = strrchr(r->filename, '/'))) ap_table_setn(r->subprocess_env, "DOCUMENT_NAME", ++t);
  6767.     else ap_table_setn(r->subprocess_env, "DOCUMENT_NAME", r->uri);
  6768. }
  6769.  
  6770. /*--------------------------------------------------------------------------*/
  6771. /* Routine de Gestionnaire (handler)                                        */
  6772. /*--------------------------------------------------------------------------*/
  6773. static int adml_handler(request_rec *r)
  6774. {
  6775.         struct timeval tval;
  6776.         struct timezone tzone = {0, 0};
  6777.         unsigned long int val;
  6778.         FILE *f;
  6779.         adml_cfg *conf;
  6780.         request_rec *parent;    /* Pour recup de la config du process parent */
  6781.         char c;
  6782.         int x;
  6783.  
  6784.         if (r->finfo.st_mode == 0)      /* Si le fichier n'existe pas, alors ERREUR 404 */
  6785.         {
  6786.                 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,"File does not exist: %s",(r->path_info ? ap_pstrcat(r->pool, r->filename, r->path_info, NULL) : r->filename));
  6787.                 return HTTP_NOT_FOUND;
  6788.         }
  6789.  
  6790.         conf = (adml_cfg *) ap_get_module_config(r->per_dir_config, &adml_module);      /* recupere la config */
  6791.         /* memcpy(&adml_cfg,conf,sizeof(adml_cfg));     Copie la configuration */
  6792.  
  6793.         /* Si la commande ModelEngine est off */
  6794.         if (!conf->engine)
  6795.         {
  6796.                 r->content_type = "text/html";
  6797.                 r->allowed |= (1 << METHODS) - 1;
  6798.                 return DECLINED;
  6799.         }
  6800.  
  6801.         /* ----------------------------------------------------------------- */
  6802.         if (!(f = ap_pfopen(r->pool, r->filename, "r")))
  6803.         {
  6804.                 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,"file permissions deny server access: %s", r->filename);
  6805.                 return HTTP_FORBIDDEN;
  6806.         }
  6807.  
  6808.         ap_hard_timeout("Model", r);    /* Initialisation du Timeout */
  6809.         conf->fichier = (char *) ap_pcalloc(r->pool, (sizeof(char) * r->finfo.st_size)+1);
  6810.  
  6811.         conf->taille_fichier = 0;
  6812.         while ((c = fgetc(f)) != EOF && conf->taille_fichier < r->finfo.st_size) conf->fichier[conf->taille_fichier++] = c;     /* Recupere toute la page en memoire */
  6813.         conf->fichier[conf->taille_fichier] = '\0';     /* Fin de chaine */
  6814.         if (ferror(f)) fprintf(stderr,"encountered error in getc() function dna module Model");
  6815.  
  6816.         ap_pfclose(r->pool, f);
  6817.         /* ----------------------------------------------------------------- */
  6818.  
  6819.         if (r->header_only)     /* reponse a une requete HEAD (n'envoi que l'entete) */
  6820.         {
  6821.                 r->content_type = "text/html"/* Definit le content_type */
  6822.                 ap_send_http_header(r);
  6823.                 ap_kill_timeout(r);
  6824.                 return HTTP_OK;
  6825.         }
  6826.  
  6827.         /* ------------------------- Initialisation ------------------------------------- */
  6828.         conf->show = TRUE;      /* Par defaut au depart, les sorties sont Vraie */
  6829.         conf->ifwhile[0].sortie = TRUE/* Toujour Vraie pour le niveau 0 */
  6830.         conf->ifwhile[0].execute = TRUE;        /* Toujour vraie pour le niveau 0 (sauf peut-etre dans le cas d'un include) */
  6831.         conf->nwhile = 0;       /* Niveau d'imbrication 0 pour les Whiles et If */
  6832.  
  6833.         if ((parent = ap_get_module_config(r->request_config, &adml_module)))   /* recupere la config d'un process parent s'il existe */
  6834.         {
  6835.                 r->subprocess_env = parent->subprocess_env;
  6836.                 ap_pool_join(parent->pool, r->pool);
  6837.                 r->finfo.st_mtime = parent->finfo.st_mtime;
  6838.  
  6839.                 if ((conf->unique_id = ap_table_get(parent->subprocess_env, "ADML_SHOW")) != NULL) conf->show = atoi(conf->unique_id)/* Recupere la variable d'environnement qui determine la valeur booleene de la sortie */
  6840.                 if ((conf->unique_id = ap_table_get(parent->subprocess_env, "ADML_EXEC")) != NULL) conf->ifwhile[0].execute = atoi(conf->unique_id);    /* Recupere la variable d'environnement qui determine la valeur booleene de execute */
  6841.  
  6842.                 conf->unique_id = ap_table_get(parent->subprocess_env, "ADML_UNIQUE_ID");       /* Recupere la variable d'environnement de la config parent si elle existe */
  6843.         }
  6844.         else
  6845.         {
  6846.                 ap_add_common_vars(r)/* Met en place les variables d'environnements generales */
  6847.                 ap_add_cgi_vars(r);          /* Mets en place les variables d'environnement pour les CGI */
  6848.                 add_vars(r);
  6849.                 conf->unique_id = NULL;
  6850.         }
  6851.      
  6852.         /* --------------- Calcul de l'identificateur unique --------------------------- */
  6853.         if (conf->unique_id == NULL)
  6854.         {
  6855.                 gettimeofday(&tval, &tzone);
  6856.                 if ((val = inet_addr(r->connection->remote_ip)) == -1) val = (unsigned long int)tval.tv_usec / 1000;
  6857.  
  6858.                 conf->unique_id = ap_psprintf(conf->pool_session, "%lu%ld%03d", val, (long)tval.tv_sec, (int)tval.tv_usec/1000);
  6859.         }
  6860.         ap_table_setn(r->subprocess_env, "ADML_UNIQUE_ID", conf->unique_id);
  6861.  
  6862.         /* ----- Initialisation de la structure ----- */
  6863.         for (x=0; x < N_MYSQL; x++)     /* Initialise la structure pour Mysql */
  6864.         {
  6865.                 conf->base_mysql[x].fconnect = FALSE;
  6866.                 conf->base_mysql[x].fbase = FALSE;
  6867.                 conf->base_mysql[x].fquery = FALSE;
  6868.                 conf->base_mysql[x].ferror = FALSE;
  6869.         }
  6870.         conf->mysql_def = 0;    /* Numero de structure par defaut */
  6871.  
  6872.         for (x=0; x < N_FORM; x++)
  6873.         {
  6874.                 conf->form[x].tab = ap_make_table(conf->pool_session, 1);       /* cree les structures form */
  6875.                 conf->form[x].pos = -1/* Position courante sur les champs (pointe sur rien par defaut) */
  6876.         }
  6877.         for (x=0; x < N_VAR; x++)
  6878.         {
  6879.                 conf->var[x].tab = ap_make_table(conf->pool_session, 1);        /* cree les structures var */
  6880.                 conf->var[x].pos = -1/* Position courante sur les champs (pointe sur rien par defaut) */
  6881.         }
  6882.         conf->form_def = 0;     /* Numero de structure par defaut */
  6883.         conf->var_def = 0;      /* Numero de structure par defaut */
  6884.  
  6885.         for (x=0; x <= N_SOCKET; x++)   /* Initialise la structure socket */
  6886.         {
  6887.                 conf->sock[x].fd = -1/* Socket ferme */
  6888.                 conf->sock[x].taille_buffer = conf->sock[x].taille_buffer_max = 0;
  6889.                 conf->sock[x].buffer = "";
  6890.  
  6891.                 conf->sock[x].last_excess = 0;
  6892.                 conf->sock[x].last_pos = 0;
  6893.                 conf->sock[x].eom = 0;
  6894.         }
  6895.  
  6896.         /* Initialisation de la structure socket SMTP */
  6897.         conf->smtp.sock.fd = -1;        /* Socket ferme */
  6898.         conf->smtp.sock.taille_buffer = conf->smtp.sock.taille_buffer_max = 0;
  6899.         conf->smtp.sock.buffer = "";
  6900.         conf->smtp.sock.last_excess = 0;
  6901.         conf->smtp.sock.last_pos = 0;
  6902.         conf->smtp.sock.eom = 0;
  6903.  
  6904.         conf->include = ap_make_table(conf->pool_session, 1);   /* Cree la table pour les Includes (qui sera detruite a la fin de la session) */
  6905.         conf->cookies.tab = ap_make_table(conf->pool_session, 1);       /* Cree la table pour les Cookies (qui sera detruite a la fin de la session) */
  6906.         conf->cookies.pos = 0/* Position courante dans la table des cookies */
  6907.         conf->headers_in_num = 0;       /* Position courante dans la table des headers_in */
  6908.  
  6909.         for (x=0; x < N_DATE; x++)
  6910.         {
  6911.                 time(&conf->secs[x]);   /* date courante */
  6912.         }
  6913.  
  6914.         /* ----- recupere le boundary s'il y en a un ----- */
  6915.         conf->boundary = "";
  6916.         if ((conf->ctemp = ap_table_get(r->headers_in, "Content-type")) != NULL)
  6917.         {
  6918.                 if ((conf->temp = strstr(conf->ctemp, "oundary=")) != NULL)
  6919.                 {
  6920.                         conf->boundary = ap_pstrdup(conf->pool_session, &conf->temp[8]);
  6921.                         if ((conf->temp = strchr(conf->boundary, ';')) != NULL) conf->temp[0] = '\0';
  6922.                 }
  6923.         }
  6924.  
  6925.         /* ----- recuperation de l'entete 'Authorization: Basic user:password' ----- */
  6926.         conf->auth_user = NULL;
  6927.         conf->auth_passwd = NULL;
  6928.         conf->auth_type = NULL;
  6929.         if ((conf->ctemp = ap_table_get(r->headers_in, "Authorization")) != NULL)
  6930.         {
  6931.                 conf->temp = ap_pstrdup(conf->pool_session, conf->ctemp);
  6932.                 conf->temp = trim(conf->temp, ' ');     /* elimine les espace devant et derriere */
  6933.                 if ((conf->temp1 = strchr(conf->temp, ' ')) != NULL)
  6934.                 {
  6935.                         conf->temp1[0] = '\0';
  6936.                         conf->temp1++;
  6937.                         conf->auth_type = conf->temp;
  6938.                         conf->temp = base64decode(conf->pool_session, conf->temp1, strlen(conf->temp1), NULL);
  6939.                         if ((conf->temp1 = strchr(conf->temp, ':')) != NULL)
  6940.                         {
  6941.                                 conf->temp1[0] = '\0';
  6942.                                 conf->auth_user = conf->temp;   /* USER */
  6943.                                 conf->auth_passwd = &conf->temp1[1];    /* PASSWORD */
  6944.                         }
  6945.                 }
  6946.         }
  6947.  
  6948.         conf->notagbr = FALSE/* Les retour chariot apres un TAG sont autorises par defaut */
  6949.         conf->nupload = 0;      /* Initialise le nombre d'elements de la structure upload */
  6950.         conf->upload_num = -1/* Position courante par defaut dans la structure upload (pointe sur rien par defaut)*/
  6951.         conf->r = r;        /* Recupere le request_rec actuel (en cas de besoin lorsque l'on ne possede que la structure conf) */
  6952.         conf->header = FALSE;   /* Le Header de la page n'est pas encore envoye */
  6953.         conf->noheader = FALSE/* Par defaut l'header doit etre envoye */
  6954.         conf->exit = 0;   /* Exit = FALSE par defaut (utiliser par le tag EXIT */
  6955.         /* ------------------------------------------ */
  6956.  
  6957.  
  6958.         recup(r);       /* Recuperation des donnees du formulaire */
  6959.  
  6960.         recup_cookies(conf);    /* recuperation des cookies */
  6961.  
  6962. /*
  6963.         ap_rputs(DOCTYPE_HTML_3_2, r);
  6964. */
  6965.  
  6966.         conf->filename = NULL/* Ont est dans le fichier principal */
  6967.         analyse_page(r, conf->fichier);
  6968.  
  6969.         for (x=0; x <= N_SOCKET; x++)   /* deconnect les socket */
  6970.         {
  6971. /* -------> A FAIRE SI NECESSAIRE (deconnection des socket encore ouverte) */
  6972.                 ap_clear_pool(conf->sock[x].p)/* netoyage des pools */
  6973.         }
  6974.         ap_clear_pool(conf->smtp.sock.p);       /* netoyage du pools de la structure socksmtp */
  6975.  
  6976.         ap_clear_pool(conf->pool_session);      /* Detruit le contenu du pool */
  6977.         for (x=0; x < N_MYSQL; x++)      /* Ferme toutes les connections Mysql */
  6978.         {
  6979.                 md_mysql_close(&conf->base_mysql[x]);
  6980.         }
  6981.  
  6982.         ap_kill_timeout(r);     /* Supprime le timeout */
  6983.  
  6984.         return OK;      /* OK, le gestionnaire a bien traite la requete ! */
  6985. }
  6986.  
  6987. /*--------------------------------------------------------------------------*/
  6988. /* Initialisation                                                           */
  6989. /*--------------------------------------------------------------------------*/
  6990. static void adml_init(server_rec *s, pool *p)
  6991. {
  6992.         ap_add_version_component("MOD_ADML/" ADML_VERSION);     /* Enregistre la version du module */
  6993. }
  6994.  
  6995. /*--------------------------------------------------------------------------*/
  6996. /* Creation d'une configuration par repertoire                              */
  6997. /*--------------------------------------------------------------------------*/
  6998. static void *adml_create_dir_config(pool *p, char *dirspec)
  6999. {
  7000.         int x;
  7001.         adml_cfg *conf;
  7002.  
  7003.         conf = (adml_cfg *) ap_pcalloc(p, sizeof(adml_cfg));    /* Alloue de l'espace pour la structure de donnees */
  7004.  
  7005.         conf->pool_tag = ap_make_sub_pool(p);   /* cree un sous-pool qui sera vide a chaque debut de nouveau TAG */
  7006.         conf->pool_session = ap_make_sub_pool(p);       /* cree un sous-pool qui sera vide a chaque debut de session */
  7007.         conf->tag = ap_make_table(conf->pool_tag, 1);   /* Cree la table pour les parametres de tag (qui sera supprimer a chaque debut de TAG */
  7008.  
  7009.         conf->tag = NULL;       /* Pour determine que la table n'a pas encore ete cree */
  7010.         conf->nwhile = 0;       /* Niveau d'imbrication 0 pour les Whiles et If */
  7011.  
  7012.         /* ---------- Les structures ---------- */
  7013.         for (x=0; x <= N_SOCKET; x++)   /* Initialise la structure socket */
  7014.         {
  7015.                 conf->sock[x].p = ap_make_sub_pool(p)/* Creation des sous pool */
  7016.         }
  7017.         conf->smtp.sock.p = ap_make_sub_pool(p);        /* Creation du sous pool pour la structure socksmtp */
  7018.  
  7019.         conf->mysql_host = "localhost";
  7020.         conf->mysql_user = conf->mysql_passwd = "";
  7021.         conf->mysql_base = NULL;
  7022.         conf->engine = FALSE;
  7023.  
  7024.     return (void *) conf;       /* retourne la structure a conserver */
  7025. }
  7026.  
  7027. /*--------------------------------------------------------------------------*/
  7028. /* Fusion d'une configuration par repertoire                                */
  7029. /*--------------------------------------------------------------------------*/
  7030. static void *adml_merge_dir_config(pool *p, void *parent_conf, void *newloc_conf)
  7031. {
  7032.  
  7033.         adml_cfg *merged_config = (adml_cfg *) ap_pcalloc(p, sizeof(adml_cfg));
  7034.         adml_cfg *pconf = (adml_cfg *) parent_conf;
  7035.         adml_cfg *nconf = (adml_cfg *) newloc_conf;
  7036.  
  7037.  
  7038.         return (void *) merged_config;
  7039. }
  7040.  
  7041. /*--------------------------------------------------------------------------*/
  7042. /* Liste des commandes (directives) du module.                              */
  7043. /*--------------------------------------------------------------------------*/
  7044. static const command_rec adml_cmds[] =
  7045. {
  7046.         {"AdmlEngine", handle_FLAG, (void *)0, RSRC_CONF, FLAG, "Mise en service du module - on|off"},
  7047.         {"AdmlMysqlHost", handle_TAKE1, (void *)0, RSRC_CONF, TAKE1, "Adresse du serveur Mysql par defaut."},
  7048.         {"AdmlMysqlUser", handle_TAKE1, (void *)1, RSRC_CONF, TAKE1, "User du serveur Mysql par defaut."},
  7049.         {"AdmlMysqlPassword", handle_TAKE1, (void *)2, RSRC_CONF, TAKE1, "Password du serveur Mysql par defaut."},
  7050.         {"AdmlMysqlBase", handle_TAKE1, (void *)3, RSRC_CONF, TAKE1, "Base du serveur Mysql par defaut."},
  7051.     {NULL}
  7052. };
  7053.  
  7054. /*--------------------------------------------------------------------------*/
  7055. /* Liste des gestionnaires (handlers) pris en compte par le module.         */
  7056. /*--------------------------------------------------------------------------*/
  7057. static const handler_rec adml_handlers[] =
  7058. {
  7059.     {"adml-handler", adml_handler},
  7060.     {NULL}
  7061. };
  7062.  
  7063. /*--------------------------------------------------------------------------*/
  7064. /* Definition du module                                                     */
  7065. /*--------------------------------------------------------------------------*/
  7066. module adml_module =
  7067. {
  7068.     STANDARD_MODULE_STUFF,
  7069.     adml_init,      /* initialiseur (module initializer) */
  7070.     adml_create_dir_config,     /* cree une structure de configuration par repertoire (per-directory config creator) */
  7071.     /* adml_merge_dir_config,    fusionne des structures de configuration par repertoire (dir config merger) */
  7072.         NULL,
  7073.     NULL,                     /* cree une structure de configuration par serveur (server config creator) */
  7074.     NULL,                     /* fusionne des structures de configuration par serveur (server config merger) */
  7075.     adml_cmds,      /* table de commandes (command table) */
  7076.     adml_handlers,            /* [7] liste des gestionnaires (list of handlers) */
  7077.     NULL,                     /* [2] traduction de gestionnaire (filename-to-URI translation) */
  7078.     NULL,                     /* [5] verification d'id_utilisateur (check/validate user_id) */
  7079.     NULL,                     /* [6] verification d'authentification (check user_id is valid *here*) */
  7080.     NULL,                     /* [4] verificateur d'acces (check access by host address) */
  7081.     NULL,                     /* [7] verificateur de type (MIME type checker/setter) */
  7082.     NULL,                     /* [8] mises au point de pre-fonctionnement (fixups) */
  7083.     NULL,                     /* [10] traceur (logger) */
  7084. #if MODULE_MAGIC_NUMBER >= 19970103
  7085.     NULL,                     /* [3] analyseur d'entete (header parser) */
  7086. #endif
  7087. #if MODULE_MAGIC_NUMBER >= 19970719
  7088.     NULL,                     /* initialisation du fils (child_init) */
  7089. #endif
  7090. #if MODULE_MAGIC_NUMBER >= 19970728
  7091.     NULL,                     /* sortie du fils (child_exit) */
  7092. #endif
  7093. #if MODULE_MAGIC_NUMBER >= 19970902
  7094.     NULL                        /* [1] requete apres lecture (post read-request) */
  7095. #endif
  7096. };

advertising

Create a Paste

Please enter your new post below (or upload a file instead):





Please note that information posted here will not expire by default. If you want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords.

fantasy-obligation