├── Brook
└── brokers
│ └── brookfclfcgibroker.pas
├── README.md
├── bbs.lpi
├── bbs.lpr
├── blowcryp.pas
├── brokers.pas
├── change.pas
├── dependencies.txt
├── fevent.pas
├── find.pas
├── forums.pas
├── frslt.pas
├── geoinfo.pas
├── info.pas
├── legal.pas
├── logout.pas
├── main.pas
├── mapping.pas
├── menu.pas
├── myaccnt.pas
├── newpost.pas
├── news.pas
├── newthm.pas
├── posts.pas
├── registerusr.pas
├── synacode.pas
├── upload.pas
└── upst.pas
/Brook/brokers/brookfclfcgibroker.pas:
--------------------------------------------------------------------------------
1 | (*
2 | Brook framework, FCL FastCGI Broker
3 |
4 | Copyright (C) 2014 Silvio Clecio
5 |
6 | See the file LICENSE.txt, included in this distribution,
7 | for details about the copyright.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 |
13 | /// 08.05.14 added mysql conncetion handling
14 | *)
15 |
16 | unit BrookFCLFCGIBroker;
17 |
18 | {$mode objfpc}{$H+}
19 |
20 | interface
21 |
22 | uses
23 | BrookClasses, BrookApplication, BrookMessages, BrookConsts, BrookHttpConsts,
24 | BrookRouter, BrookUtils, BrookHttpDefsBroker, HttpDefs, CustWeb, CustFCGI,
25 | Classes, SysUtils, Variants, FmtBCD, mysql55conn, sqldb;
26 |
27 | type
28 | TBrookFCGIApplication = class;
29 |
30 | { TBrookApplication }
31 |
32 | TBrookApplication = class(TBrookInterfacedObject, IBrookApplication)
33 | private
34 | FApp: TBrookFCGIApplication;
35 | function GetTerminated: Boolean;
36 | public
37 | constructor Create; virtual;
38 | destructor Destroy; override;
39 | function Instance: TObject;
40 | procedure Run;
41 | procedure Terminate;
42 | property Terminated: Boolean read GetTerminated;
43 | end;
44 |
45 | { TBrookFCGIApplication }
46 |
47 | TBrookFCGIApplication = class(TCustomFCGIApplication)
48 | protected
49 | function InitializeWebHandler: TWebHandler; override;
50 | end;
51 |
52 | { TBrookFCGIRequest }
53 |
54 | TBrookFCGIRequest = class(TFCGIRequest)
55 | protected
56 | procedure DeleteTempUploadedFiles; override;
57 | function GetTempUploadFileName(
58 | const {%H-}AName, AFileName: string; {%H-}ASize: Int64): string; override;
59 | function RequestUploadDir: string; override;
60 | procedure InitRequestVars; override;
61 | procedure HandleUnknownEncoding(
62 | const AContentType: string; AStream: TStream); override;
63 | end;
64 |
65 | { TBrookFCGIResponse }
66 |
67 | TBrookFCGIResponse = class(TFCGIResponse)
68 | protected
69 | procedure CollectHeaders(AHeaders: TStrings); override;
70 | end;
71 |
72 | { TBrookFCGIHandler }
73 |
74 | TBrookFCGIHandler = class(TFCGIHandler)
75 | protected
76 | function CreateRequest: TFCGIRequest; override;
77 | function CreateResponse(ARequest: TFCGIRequest): TFCGIResponse; override;
78 | public
79 | procedure HandleRequest(ARequest: TRequest; AResponse: TResponse); override;
80 | procedure ShowRequestException(R: TResponse; E: Exception); override;
81 | end;
82 |
83 | VAR
84 | conn : TMySQL55Connection;
85 | transaction: TSQLTransaction;
86 |
87 | implementation
88 |
89 | { TBrookApplication }
90 |
91 | function TBrookApplication.GetTerminated: Boolean;
92 | begin
93 | Result := FApp.Terminated;
94 | end;
95 |
96 | constructor TBrookApplication.Create;
97 | begin
98 | FApp := TBrookFCGIApplication.Create(nil);
99 | FApp.Initialize;
100 | end;
101 |
102 | destructor TBrookApplication.Destroy;
103 | begin
104 | FApp.Free;
105 | conn.Connected := false;
106 | transaction.free;
107 | conn.free;
108 | inherited Destroy;
109 | end;
110 |
111 | function TBrookApplication.Instance: TObject;
112 | begin
113 | Result := FApp;
114 | end;
115 |
116 | procedure TBrookApplication.Run;
117 | begin
118 | if BrookSettings.Port <> 0 then
119 | FApp.Port := BrookSettings.Port;
120 |
121 | conn := TMySQL55Connection.Create(nil);
122 | transaction := TSQLTransaction.Create(nil);
123 | conn.HostName := 'localhost';
124 | conn.Password := 'secret';
125 | conn.UserName := 'bbsworker';
126 | conn.DatabaseName := 'bbs';
127 | conn.CharSet := 'utf8';
128 | conn.Connected := True;
129 | conn.Transaction := transaction;
130 |
131 | FApp.Run;
132 | end;
133 |
134 | procedure TBrookApplication.Terminate;
135 | begin
136 | FApp.Terminate;
137 | end;
138 |
139 | { TBrookFCGIApplication }
140 |
141 | function TBrookFCGIApplication.InitializeWebHandler: TWebHandler;
142 | begin
143 | Result := TBrookFCGIHandler.Create(Self);
144 | end;
145 |
146 | { TBrookFCGIRequest }
147 |
148 | procedure TBrookFCGIRequest.DeleteTempUploadedFiles;
149 | begin
150 | if BrookSettings.DeleteUploadedFiles then
151 | inherited;
152 | end;
153 |
154 | function TBrookFCGIRequest.GetTempUploadFileName(
155 | const AName, AFileName: string; ASize: Int64): string;
156 | begin
157 | if BrookSettings.KeepUploadedNames then
158 | Result := RequestUploadDir + AFileName
159 | else
160 | Result := inherited GetTempUploadFileName(AName, AFileName, ASize);
161 | end;
162 |
163 | function TBrookFCGIRequest.RequestUploadDir: string;
164 | begin
165 | Result := BrookSettings.DirectoryForUploads;
166 | if Result = '' then
167 | Result := GetTempDir;
168 | Result := IncludeTrailingPathDelimiter(Result);
169 | end;
170 |
171 | procedure TBrookFCGIRequest.InitRequestVars;
172 | var
173 | VMethod: ShortString;
174 | begin
175 | VMethod := Method;
176 | if VMethod = ES then
177 | raise Exception.Create(SBrookNoRequestMethodError);
178 | case VMethod of
179 | BROOK_HTTP_REQUEST_METHOD_DELETE, BROOK_HTTP_REQUEST_METHOD_PUT,
180 | BROOK_HTTP_REQUEST_METHOD_PATCH:
181 | begin
182 | InitPostVars;
183 | if HandleGetOnPost then
184 | InitGetVars;
185 | end;
186 | else
187 | inherited;
188 | end;
189 | end;
190 |
191 | procedure TBrookFCGIRequest.HandleUnknownEncoding(const AContentType: string;
192 | AStream: TStream);
193 | begin
194 | if not BrookHandleUnknownEncoding(Self, AContentType, AStream) then
195 | inherited HandleUnknownEncoding(AContentType, AStream);
196 | end;
197 |
198 | { TBrookFCGIResponse }
199 |
200 | procedure TBrookFCGIResponse.CollectHeaders(AHeaders: TStrings);
201 | begin
202 | AHeaders.Add(BROOK_HTTP_HEADER_X_POWERED_BY + HS +
203 | 'Brook framework and FCL-Web.');
204 | inherited CollectHeaders(AHeaders);
205 | end;
206 |
207 | { TBrookFCGIHandler }
208 |
209 | function TBrookFCGIHandler.CreateRequest: TFCGIRequest;
210 | begin
211 | Result := TBrookFCGIRequest.Create;
212 | if ApplicationURL = ES then
213 | ApplicationURL := TBrookRouter.RootUrl;
214 | end;
215 |
216 | function TBrookFCGIHandler.CreateResponse(ARequest: TFCGIRequest): TFCGIResponse;
217 | begin
218 | Result := TBrookFCGIResponse.Create(ARequest);
219 | end;
220 |
221 | procedure TBrookFCGIHandler.HandleRequest(ARequest: TRequest; AResponse: TResponse);
222 | begin
223 | AResponse.ContentType := BrookFormatContentType;
224 | try
225 | TBrookRouter.Service.Route(ARequest, AResponse);
226 | TBrookFCGIRequest(ARequest).DeleteTempUploadedFiles;
227 | except
228 | on E: Exception do
229 | ShowRequestException(AResponse, E);
230 | end;
231 | end;
232 |
233 | procedure TBrookFCGIHandler.ShowRequestException(R: TResponse; E: Exception);
234 | begin
235 | BrookShowRequestException(Self, R, E);
236 | end;
237 |
238 | initialization
239 | BrookRegisterApp(TBrookApplication.Create);
240 |
241 | end.
242 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | EasyBBS
2 | =======
3 |
4 | BBS System based on Lazarus and Brook Framework
5 |
--------------------------------------------------------------------------------
/bbs.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
--------------------------------------------------------------------------------
/bbs.lpr:
--------------------------------------------------------------------------------
1 | program bbs;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | uses
6 | BrookApplication, Brokers, synacode, Mapping, main, forums, RegisterUsr,
7 | posts, Logout, info, myAccnt, newThm, newPost, change, legal, fevent, Menu,
8 | upst, find, frslt, geoinfo, news;
9 |
10 | {$R *.res}
11 |
12 | begin
13 | BrookApp.Run;
14 | end.
15 |
--------------------------------------------------------------------------------
/blowcryp.pas:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////
2 | // funktion : Hilfsunit mit oft gebrauchten komponenten
3 | // Datum : 03.08.2013
4 | // modified : 01.03.2014
5 | // 23.04.2014 BF 2.6.4 -> BF 3.0.0
6 | // 08.05.2014 ip_ntoa & ip_aton change integer to int64
7 |
8 | unit BlowCryp;
9 |
10 | {$mode objfpc}{$H+}
11 |
12 | interface
13 |
14 | uses
15 | BrookHTTPConsts, BrookConsts, HTTPDefs, BrookHTTPClient, BrookFCLHTTPClientBroker,
16 | Classes, SysUtils, Variants, FmtBCD, blowfish;
17 |
18 | type
19 | paraType = record // lokal vars for get/post handlers
20 | VSession : string ;
21 | sError: string ;
22 | sTopic : string ;
23 | sID : string ;
24 | sPst : string ;
25 | text1 : string ;
26 | text2 : string ;
27 | sCmd : string;
28 | lastError : string;
29 | userID : integer;
30 | sip : string; // client ip
31 | v_order : String;
32 | v_page : String;
33 | v_rec : String;
34 | v_eof : String;
35 | end;
36 |
37 | sessInfType = record // session record
38 | rid : string;
39 | id : string;
40 | user_id: string;
41 | forum_id: string;
42 | is_active: string;
43 | last_forum: string;
44 | browser: string; // client browser
45 | sip : string; // client ip
46 | sLat : string;
47 | sLong : string;
48 | latitude: string;
49 | longitude: string;
50 | accuracy : string;
51 | forwarded_for : string; // footer infos start
52 | v_order : String;
53 | v_page : String;
54 | v_rec : String;
55 | v_eof : String;
56 | viewonline : string;
57 | autologin : string;
58 | admin : string;
59 | lastsearch : string;
60 | lastlogin : String;
61 | last_post_cnt : String; // footer infos end
62 | login : string;
63 | logout : string;
64 | end;
65 |
66 |
67 | function ip_ntoa(nip: int64):string;
68 | function ip_aton(sip: string):int64;
69 | procedure GetIPLatLon( CONST sURL_sip:String; VAR sLat, sLong:STRING );
70 | function sUpdate(const s1,s2,s3:String):String;
71 | function encrypt(inStrg: string): string;
72 | function decrypt(inStrg: string): string;
73 | procedure codeSessionID( VAR sesnRec: sessInfType );
74 | function decodeSessionID(VAR myPara: ParaType ):integer;
75 | function isSessionValid( VAR myPara: ParaType):boolean;
76 | FUNCTION SecuredStr(CONST S : STRING) : STRING;
77 | Function sPlus( sIn: String ) : String;
78 | Function sMinus( sIn: String ) : String;
79 | function StrToHex(const value:string):string;
80 | function StripHTML(S: string): string;
81 | function iif( bPara: Boolean; sTrue, sFalse:String):String;
82 |
83 | implementation
84 |
85 |
86 | function StripHTML(S: string): string;
87 | var
88 | TagBegin, TagEnd, TagLength: integer;
89 | begin
90 | TagBegin := Pos( '<', S); // search position of first <
91 |
92 | while (TagBegin > 0) do begin // while there is a < in S
93 | TagEnd := Pos('>', S); // find the matching >
94 | TagLength := TagEnd - TagBegin + 1;
95 | Delete(S, TagBegin, TagLength); // delete the tag
96 | TagBegin:= Pos( '<', S); // search for next <
97 | end;
98 |
99 | Result := S; // give the result
100 | end;
101 |
102 |
103 | Function sPlus( sIn: String ) : String;
104 | var
105 | i: integer;
106 | begin
107 | try
108 | i := StrToInt( sIn );
109 | except
110 | on e: Exception do i := 0;
111 | end;
112 |
113 | sPlus := IntToStr( i+1 );
114 | end;
115 |
116 | Function sMinus( sIn: String ) : String;
117 | var
118 | i: integer;
119 | begin
120 | try
121 | i := StrToInt( sIn );
122 | except
123 | on e: Exception do i := 0;
124 | end;
125 |
126 | if i > 1 then
127 | sMinus := IntToStr( i-1 )
128 | else
129 | sMinus := '0';
130 |
131 | end;
132 |
133 | function iif( bPara: Boolean; sTrue, sFalse:String):String;
134 | begin
135 | if bPara then
136 | iif := sTrue
137 | else
138 | iif := sFalse;
139 | end;
140 |
141 | function ip_ntoa(nip: int64):string;
142 | var
143 | o1,o2,o3,o4 : int64;
144 | begin
145 | o1 := ( nip DIV 16777216 ) MOD 256;
146 | o2 := ( nip DIV 65536 ) MOD 256;
147 | o3 := ( nip DIV 256 ) MOD 256;
148 | o4 := ( nip ) MOD 256;
149 | ip_ntoa := IntToStr(o1) + '.' +
150 | IntToStr(o2) + '.' +
151 | IntToStr(o3) + '.' +
152 | IntToStr(o4) ;
153 | end;
154 |
155 |
156 | function ip_aton(sip: string):int64;
157 | var
158 | o1,o2,o3,o4 : int64;
159 | integer_ip : int64;
160 | Oktett : TStringList;
161 |
162 | begin
163 | Oktett := TStringList.Create;
164 | Oktett.Delimiter := '.';
165 | Oktett.DelimitedText := sip;
166 |
167 | try
168 | o1 := StrToInt( Oktett[0] );
169 | o2 := StrToInt( Oktett[1] );
170 | o3 := StrToInt( Oktett[2] );
171 | o4 := StrToInt( Oktett[3] );
172 | if ( o1 < 0 ) or ( o1 > 255 ) or
173 | ( o2 < 0 ) or ( o2 > 255 ) or
174 | ( o3 < 0 ) or ( o3 > 255 ) or
175 | ( o4 < 0 ) or ( o4 > 255 ) then raise Exception.Create('Oktett Fehler: Eingabe < 0 oder > 255');
176 | integer_ip := 16777216 * o1
177 | + 65536 * o2
178 | + 256 * o3
179 | + o4 ;
180 | except
181 | on e: Exception do
182 | begin
183 | integer_ip := 0;
184 | // ShowMessage('Falsches IP Format: ' + e.Message );
185 | end;
186 | end;
187 | Oktett.Free;
188 | ip_aton := integer_ip;
189 | end;
190 |
191 | function iTime():integer;
192 | var
193 | Hour, Min, Sec, MSec, Y, M, D : Word;
194 | begin
195 | DecodeTime(now(), Hour, Min, Sec, MSec);
196 | DecodeDate(now(), Y, M, D);
197 | iTime := Min + 60 * Hour + 1440 * D;
198 | end;
199 |
200 |
201 | // build session id based on
202 | // user IP & user.iduser + now()
203 | procedure codeSessionID( VAR sesnRec: sessInfType );
204 | begin
205 | sesnRec.id := encrypt(
206 | inttostr(ip_aton( sesnRec.sip ))+
207 | '|' + sesnRec.user_id +
208 | '|' + inttostr( iTime ) ) ;
209 | end;
210 |
211 |
212 |
213 | function decodeSessionID( VAR myPara: ParaType ):integer;
214 | var
215 | i : integer;
216 | sInfo : TStringList;
217 |
218 |
219 | begin
220 | // exit on empty sesion string
221 | if myPara.VSession = '' then
222 | begin
223 | myPara.userID := 0;
224 | decodeSessionID := 0;
225 | exit;
226 | end;
227 |
228 | // parse session string
229 | sInfo := TStringList.Create;
230 | sInfo.Delimiter := '|';
231 | sInfo.DelimitedText := decrypt(myPara.VSession);
232 |
233 | // handle special ip '0.0.0.1' ( used in register mail )
234 | if sInfo[0] = '1' then sInfo[0] := inttostr(ip_aton( myPara.sIP ));
235 |
236 | // check ip
237 | if sInfo[0] <> inttostr(ip_aton( myPara.sIP )) then
238 | begin
239 | // error on ip diff
240 | myPara.userID := 0;
241 | decodeSessionID := -1;
242 | sInfo.Free;
243 | exit;
244 | end;
245 |
246 | // nothing is granted !
247 | try
248 | myPara.userID := strtoint( sInfo[1] );
249 | i := strtoint( sInfo[2] );
250 | except
251 | myPara.userID := 0;
252 | i := 0;
253 | end;
254 |
255 | decodeSessionID := itime() - i; // calc sesn age( mins)
256 | sInfo.Free;
257 | end;
258 |
259 | // check session
260 | // function isSessionValid( VSession: string; VAR sError:String; VAR userID:integer ):boolean;
261 | function isSessionValid( VAR myPara: ParaType):boolean;
262 | VAR
263 | ttl:integer ; // time to life
264 | begin
265 | isSessionValid := FALSE;
266 | IF myPara.VSession <> '' then // exit on empty vSession
267 | begin
268 | ttl := decodeSessionID(myPara );
269 | if ttl > 60 then // timeout in minutes
270 | begin
271 | myPara.LastError := 'Session abgelaufen.';
272 | exit;
273 | end;
274 | if ttl < 0 then // different ip
275 | begin
276 | myPara.LastError := 'Session ungültig.';
277 | exit;
278 | end;
279 | isSessionValid := true; // set session flag
280 | end;
281 |
282 | end;
283 |
284 |
285 | /// replaceString wrapper
286 | function sUpdate (const s1,s2,s3:String):String;
287 | begin
288 | result:= StringReplace(s1, s2, s3, [rfReplaceAll]);
289 | end;
290 |
291 |
292 | // procedure GetIPLatLon( CONST sip:String; VAR sLat, sLong:STRING );
293 | // procedure GetIPLatLon( CONST conn: TMySQL55Connection; sip:String; VAR sLat, sLong:STRING );
294 | procedure GetIPLatLon( CONST sURL_sip:String; VAR sLat, sLong:STRING );
295 |
296 | var
297 | VClient: TBrookHTTPClient;
298 | VHttp : TBrookHTTPDef = nil;
299 | sInfo : TStringList;
300 |
301 | begin
302 | VClient := TBrookHTTPClient.Create('fclweb');
303 | sInfo := TStringList.Create;
304 | sInfo.Delimiter := ',';
305 |
306 | try
307 | VClient.Prepare(VHttp);
308 | VHttp.Method := 'GET';
309 | VHttp.Url := sURL_sip ;
310 | VClient.Request(VHttp);
311 | VHttp.Document.Position := 0;
312 | sInfo.LoadFromStream(VHttp.Document);
313 |
314 | // cut down JSON string
315 | // sTest := '{"ip":"109.128.12.96","country_code":"BE","region_code":"11","city":"Brussels","zipcode":"",
316 | // "latitude":50.8333 ,"longitude":4.3333 ,"region_name":"Brussels Hoofdstedelijk Gewest","country_name":"Belgium"}';
317 | sInfo.DelimitedText := sUpdate( sUpdate( sUpdate(sInfo.Text , '{', '' ), '}', '' ), '"', '' );
318 | sLat := sUpdate( sInfo[5], 'latitude:', '' );
319 | sLong := sUpdate( sInfo[6], 'longitude:', '' );
320 |
321 | except
322 | // no answer from service
323 | on e: Exception do
324 | begin
325 | sLat := '0';
326 | sLong := '0';
327 | end;
328 | end;
329 |
330 | VHttp.Free;
331 | VClient.Free;
332 | sInfo.Free;
333 |
334 |
335 |
336 | end;
337 |
338 | FUNCTION SecuredStr(CONST S : STRING) : STRING;
339 | var
340 | sTemp : string;
341 | flag : boolean;
342 |
343 | BEGIN
344 | // silent correction
345 | sTemp := s;
346 | sTemp := sUpdate(sTemp, '''', ''); // remove quotes
347 | sTemp := sUpdate(sTemp, '"',''); // remove DQ
348 | SecuredStr:= sUpdate(sTemp, ';',''); // remove Semicolon
349 |
350 | // punisher action: return empty string
351 | sTemp := UpperCase(sTemp);
352 | flag := Pos('AND', sTemp) > 0 ;
353 | flag := flag OR ( Pos('DROP', sTemp) > 0 );
354 | flag := flag OR ( Pos('OR 1', sTemp) > 0 );
355 | flag := flag OR ( Pos('LIKE', sTemp) > 0 );
356 | flag := flag OR ( Pos('WHERE', sTemp)> 0 );
357 | flag := flag OR ( Pos('CREATE', sTemp)> 0 );
358 | if flag then SecuredStr:= '';
359 |
360 | END;
361 |
362 |
363 |
364 | {**************************************************************************
365 | * NAME: StringToHexStr
366 | * DESC: Konvertiert einen String in eine hexadezimale Darstellung
367 | *************************************************************************}
368 | function StrToHex(const value:string):string;
369 | begin
370 | SetLength(Result, Length(value)*2); // es wird doppelter Platz benötigt
371 | if Length(value) > 0 then
372 | BinToHex(PChar(value), PChar(Result), Length(value));
373 | end;
374 |
375 |
376 | {**************************************************************************
377 | * NAME: HexStrToString
378 | * DESC: Dekodiert einen hexadezimalen String
379 | *************************************************************************}
380 | function HexToStr(const value:string):string;
381 | begin
382 | SetLength(Result, Length(value) div 2); // es wird halber Platz benötigt
383 | if Length(value) > 0 then
384 | HexToBin(PChar(value), PChar(Result), Length(value));
385 | end;
386 |
387 |
388 |
389 | /// blowfish crypt functions
390 | function encrypt(inStrg: string): string;
391 | var
392 | s1: TStringStream;
393 | bf: TBlowfishEncryptStream;
394 |
395 | begin
396 | if inStrg ='' then exit;
397 | s1:=TStringStream.Create(''); // make sure destination stream is blank
398 | bf:=TBlowfishEncryptStream.Create('Bahn#1hof', s1); // writes to destination stream
399 | bf.writeAnsiString( inStrg );
400 | bf.free;
401 | result:= StrToHex ( s1.datastring ) ;
402 | s1.free;
403 |
404 | end;
405 |
406 | function decrypt(inStrg: string): string;
407 | var
408 | s2: TStringStream;
409 | bf: TBlowfishDecryptStream;
410 |
411 | begin
412 | if inStrg ='' then exit;
413 | s2:=TStringStream.Create( HexToStr(inStrg) ); // fill stream
414 | bf:=TBlowfishDecryptStream.Create('Bahn#1hof', s2); // create blowfish stream
415 | result:= bf.readAnsiString ; // copy stream contents to destination
416 | bf.free;
417 | s2.free;
418 |
419 | end;
420 |
421 |
422 | end.
423 |
424 |
425 |
426 |
--------------------------------------------------------------------------------
/brokers.pas:
--------------------------------------------------------------------------------
1 | unit Brokers;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | interface
6 |
7 | uses
8 | BrookFCLFCGIBroker, SysUtils, BrookUtils, BrookHTTPConsts;
9 |
10 | implementation
11 | const
12 | HTML_TPL = '
%s %s %s%s';
13 |
14 | function HTML(const ATitle, AError, AMsg, ATrace: string): string;
15 | begin
16 | Result := Format(HTML_TPL, [ATitle, AError, AMsg, ATrace]);
17 | end;
18 |
19 | initialization
20 | BrookSettings.Charset := BROOK_HTTP_CHARSET_UTF_8;
21 | BrookSettings.Page404 := HTML('Page not found', '404 - Page not found', 'Click here to go to home page ...', '');
22 | BrookSettings.Page500 := HTML('Internal server error','500 - Internal server error', 'Error: @error',' Trace: @trace');
23 | BrookSettings.DirectoryForUploads := 'C:\Apache22\fcgi-bin\upld';
24 | end.
25 |
26 |
--------------------------------------------------------------------------------
/change.pas:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////
2 | // file : change.pas
3 | // erstellt : 01.03.14
4 | // called via: 'cgi1/change?B2=xx&ID=xx&sesn=xx&Pst=xx
5 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
6 |
7 |
8 | unit change;
9 |
10 | {$mode objfpc}{$H+}
11 |
12 | interface
13 |
14 | uses
15 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils,
16 | Variants, FmtBCD, sqldb, mapping, blowcryp, menu;
17 |
18 |
19 | type
20 | TChange = class(TBrookAction)
21 | public
22 | procedure Get; override;
23 | procedure Post; override;
24 | procedure HandlePst( VAR myPara: ParaType);
25 | procedure InfoPstDelete( VAR myPara: ParaType);
26 | procedure EditTpc ( VAR myPara: ParaType );
27 | procedure PstDelete( VAR myPara: ParaType );
28 | procedure Pst_Save ( VAR myPara: ParaType );
29 | procedure Tpc_Save ( VAR myPara: ParaType );
30 | end;
31 |
32 | implementation
33 |
34 |
35 | ////////////////////////////////////////////////////////////
36 | // show post form in edit mode
37 | //
38 | procedure TChange.HandlePst( VAR myPara: ParaType);
39 | VAR
40 | memFrm : ForInfType ;
41 | memTpc : TopInfType ;
42 | PstFrm : PstInfType ;
43 | usrFrm1: usrInfType ;
44 | mySessn: sessInfType;
45 |
46 |
47 | begin
48 |
49 | // read session record
50 | paraTypeInit('change?', myPara );
51 | mySessn.id := mypara.VSession;
52 | sesn_Read( conn, mySessn );
53 | sesn_copy_para( mySessn, myPara );
54 |
55 |
56 | // read posts record
57 | PstFrm.id := myPara.sID;
58 | posts_read( BrookFCLFCGIBroker.conn, PstFrm );
59 | if PstFrm.id = '' then
60 | begin
61 | Render(err_page, ['Posting ID fehlt.']);
62 | exit;
63 | end;
64 |
65 | // read related records
66 | memTpc.id := PstFrm.topic_id;
67 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
68 | ReadUsr( BrookFCLFCGIBroker.conn, 'WHERE iduser=' + PstFrm.user_id, usrFrm1 );
69 | ReadForum ( BrookFCLFCGIBroker.conn, 'where id=' + PstFrm.forum_id, memFrm );
70 |
71 |
72 | // start render
73 | myPara.sID := memTpc.forum_id;
74 | myPara.sPst := memFrm.fName;
75 | myPara.sTopic := memTpc.title;
76 |
77 | Render('bbs_editpst.html', [make_Header_APosts( myPara ), // Header Menu
78 | showUsrImage(usrFrm1), // UsrImage(conn, usrFrm1.iduser),
79 | showUsrInfo(usrFrm1), // Usr Info
80 | usrFrm1.Name, // Column 2 Usr Name
81 | memFrm.fName, // C2 Topic Header
82 | PstFrm.post_subject, // C2 Theme - editable
83 | PstFrm.post_text, // C2 Text - editable
84 | myPara.VSession,
85 | PstFrm.id,
86 | make_Footer( BrookFCLFCGIBroker.conn, mypara ) ]);
87 |
88 | end;
89 |
90 | procedure TChange.InfoPstDelete( VAR myPara: ParaType);
91 | VAR
92 | sBody : String;
93 | PstFrm : PstInfType;
94 | memFrm : ForInfType ;
95 | memTpc : TopInfType ;
96 | usrFrm1: usrInfType;
97 | mySessn: sessInfType;
98 |
99 |
100 | begin
101 |
102 | // read session record
103 | paraTypeInit('change?', myPara );
104 | mySessn.id := mypara.VSession;
105 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
106 | sesn_copy_para( mySessn, myPara );
107 |
108 | // read posts record
109 | PstFrm.id := myPara.sID;
110 | posts_read( BrookFCLFCGIBroker.conn, PstFrm );
111 | if PstFrm.id = '' then
112 | begin
113 | Render(err_page, ['Posting ID fehlt.']);
114 | exit;
115 | end;
116 |
117 | // read related recs
118 | memTpc.id:= PstFrm.topic_id;
119 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
120 | ReadUsr( BrookFCLFCGIBroker.conn, 'WHERE iduser='+PstFrm.user_id, usrFrm1 );
121 | ReadForum ( BrookFCLFCGIBroker.conn, 'where id=' + PstFrm.forum_id, memFrm );
122 |
123 | // delete confirm body
124 | sBody := sUpdate( delpst,'%%1', usrFrm1.Name );
125 | sBody := sUpdate( sBody, '%%2', PstFrm.post_time );
126 | sBody := sUpdate( sBody, '%%3', PstFrm.post_text );
127 | sBody := sUpdate( sBody, '%%4', PstFrm.id );
128 | sBody := sUpdate( sBody, '%%5', myPara.VSession );
129 | sBody := sUpdate( sBody, '%%6', showUsrImage(usrFrm1));
130 | sBody := sUpdate( sBody, '%%7', showUsrInfo(usrFrm1));
131 |
132 | // start render
133 | mypara.sCmd := '0'; // '0' no navi btns
134 | myPara.sID := memTpc.forum_id;
135 | myPara.sPst := memFrm.fName;
136 | myPara.sTopic := memTpc.title;
137 |
138 | Render('bbs_thread.html', [make_Header_APosts( myPara ), // header
139 | sBody, // topic record
140 | make_Footer(BrookFCLFCGIBroker.conn,mypara)] ); // footer
141 |
142 | end;
143 |
144 | procedure TChange.EditTpc( VAR myPara: ParaType);
145 | VAR
146 | memFrm : ForInfType ;
147 | memTpc : TopInfType ;
148 | usrFrm1: usrInfType ;
149 |
150 |
151 | begin
152 |
153 |
154 | // copy to record
155 | memTpc.id:= myPara.sID;
156 | Topic_Read( conn, memTpc );
157 | ReadForum ( conn, 'where id=' + memTpc.forum_id, memFrm );
158 | ReadUsr ( conn, 'where iduser=' + memTpc.poster, usrFrm1 );
159 |
160 | // start render
161 | mypara.sCmd := '0'; // '0' no navi btns
162 | myPara.sID := memTpc.forum_id;
163 | myPara.sPst := memFrm.fName;
164 | myPara.sTopic := memTpc.title;
165 | Render('bbs_edithm.html', [ make_Header_APosts( myPara ), // header
166 | showUsrImage(usrFrm1), // Usr Image
167 | showUsrInfo(usrFrm1), // Usr Info
168 | usrFrm1.Name, // Column2 Usr Name
169 | memFrm.fName, // Column2 Forum Name
170 | memTpc.title, // Column2 Thema Header - editable
171 | memTpc.topic_text, // Column2 Thema Text - editable
172 | myPara.VSession, // Hidden Session ID
173 | memTpc.id, // Hidden Topic ID
174 | make_Footer(BrookFCLFCGIBroker.conn ,mypara) ]); // footer w/o navi
175 |
176 | end;
177 |
178 | ///////////////////////////////////////////////////////
179 | // procedure : TChange.Get;
180 | // description : Get Handler for bbs_thread.html form
181 | // Dispatch to procs
182 |
183 | procedure TChange.Get;
184 | VAR
185 | mode : Integer;
186 | myPara : ParaType;
187 |
188 | begin
189 |
190 | // read paras
191 | myPara.VSession := Params.Values['sesn'];
192 | myPara.sTopic := Params.Values['Tpc'];
193 | myPara.sPst := Params.Values['Pst'];
194 | myPara.sID := Params.Values['ID'];
195 | myPara.sCmd := Params.Values['B2'];
196 | myPara.sCmd += Params.Values['B3']; // form submits B2 or B3
197 | // check paras
198 | mypara.sip:= TheRequest.RemoteAddress;
199 | if NOT isSessionValid( mypara ) then
200 | begin
201 | Render(err_page, [myPara.LastError]);
202 | exit;
203 | end;
204 |
205 | case myPara.sCmd of
206 | 'chgtpc' : mode := 1; // change a topic
207 | 'chngpst' : mode := 2; // change a posting
208 | 'deltpst' : mode := 3; // delete a posting
209 | else
210 | begin
211 | Render(err_page, ['Funktion fehlt oder unbekannt: ' + myPara.sCmd ]);
212 | exit;
213 | end;
214 | end;
215 |
216 | if (mode = 1) AND (myPara.sTopic = '') then
217 | begin
218 | Render(err_page, ['Topic ID fehlt.']);
219 | exit;
220 | end;
221 |
222 | if (mode = 2) AND (myPara.sPst = '') then
223 | begin
224 | Render(err_page, ['Nachricht ID fehlt.']);
225 | exit;
226 | end;
227 |
228 | if (mode = 3) AND (myPara.sPst = '') then
229 | begin
230 | Render(err_page, ['Nachricht ID fehlt.']);
231 | exit;
232 | end;
233 |
234 | /// call info procedures - last chance for user to abort
235 | case mode of
236 | 1 : EditTpc(myPara) ;
237 | 2 : HandlePst(myPara) ;
238 | 3 : InfoPstDelete(myPara);
239 | end;
240 |
241 | end;
242 |
243 | /// DELETE Button Action
244 | procedure TChange.PstDelete( VAR myPara: ParaType);
245 | VAR
246 | PstFrm : PstInfType;
247 | usrFrm1: usrInfType;
248 | memFrm : ForInfType ;
249 | memTpc : TopInfType ;
250 |
251 | begin
252 |
253 | // read posts to rescue topic_id, forum_id and user_id
254 | PstFrm.id := myPara.sID;
255 | posts_read( BrookFCLFCGIBroker.conn, PstFrm );
256 | if PstFrm.id = '' then
257 | begin
258 | Render(err_page, ['Nachricht fehlt.']);
259 | exit;
260 | end;
261 |
262 | // read related recs
263 | memTpc.id := PstFrm.topic_id;
264 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
265 | ReadForum ( BrookFCLFCGIBroker.conn, 'where id=' + PstFrm.forum_id, memFrm );
266 | ReadUsr(BrookFCLFCGIBroker.conn, 'where iduser=' + PstFrm.user_id, usrFrm1 );
267 |
268 | // delete posting
269 | myPara.LastError := posts_Delete( BrookFCLFCGIBroker.conn, PstFrm.id );
270 | if myPara.LastError <> '' then
271 | begin
272 | Render(err_page, ['Fehler beim Löschen der Nachricht: ' + myPara.LastError]);
273 | exit;
274 | end;
275 |
276 | // refresh counters
277 | // update topic
278 | memTpc.views := sPlus( memTpc.views );
279 | memTpc.replies := sMinus( memTpc.replies );
280 | memTpc.replies_real := sMinus( memTpc.replies_real );
281 | memTpc.last_poster_id := PstFrm.user_id ;
282 | memTpc.last_poster_name := usrFrm1.Name;
283 | memTpc.last_view_time := DateTimeToStr(now) ;
284 |
285 | myPara.LastError := Topic_Update( BrookFCLFCGIBroker.conn, memTpc );
286 | if myPara.LastError <> '' then
287 | begin
288 | Render(err_page, ['Fehler beim Aktualisieren des Themas: ' + myPara.LastError]);
289 | exit;
290 | end;
291 |
292 | // update forum
293 | memFrm.posts := sMinus( memFrm.posts );
294 | memFrm.last_poster_id := usrFrm1.iduser ;
295 | memFrm.last_poster_name := usrFrm1.Name;
296 | myPara.LastError := Upd_Forum( BrookFCLFCGIBroker.conn, memFrm );
297 | if myPara.LastError <> '' then
298 | begin
299 | Render(err_page, ['Fehler beim Aktualisieren des Forums: ' +myPara.LastError]);
300 | exit;
301 | end;
302 |
303 | redirect ('topic?ID=' + PstFrm.forum_id + '&Tpc=' + PstFrm.topic_id + '&sesn=' + myPara.VSession, 302);
304 | end;
305 |
306 | procedure TChange.Pst_Save ( VAR myPara: ParaType);
307 | VAR
308 | PstFrm : PstInfType;
309 | usrFrm1: usrInfType;
310 | memFrm : ForInfType ;
311 | memTpc : TopInfType ;
312 |
313 |
314 | begin
315 |
316 | // read posts record
317 | PstFrm.id := myPara.sID;
318 | posts_read( BrookFCLFCGIBroker.conn, PstFrm );
319 | if PstFrm.id = '' then
320 | begin
321 | Render(err_page, ['Posting ID zum Update fehlt.' + myPara.sID + '--' ]);
322 | exit;
323 | end;
324 |
325 | // read related recs
326 | memTpc.id := PstFrm.topic_id;
327 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
328 | ReadUsr( BrookFCLFCGIBroker.conn, 'WHERE iduser=' + PstFrm.user_id, usrFrm1 );
329 | ReadForum ( BrookFCLFCGIBroker.conn, 'where id=' + PstFrm.forum_id, memFrm );
330 |
331 | // update posting
332 | PstFrm.post_subject := myPara.text1;
333 | PstFrm.post_text := myPara.text2;
334 | PstFrm.post_edit_count := sPlus( PstFrm.post_edit_count );
335 | PstFrm.post_edit_time := DateTimeToStr(now) ;
336 | PstFrm.post_edit_reason := myPara.sCmd;
337 | PstFrm.post_edit_user := usrFrm1.iduser;
338 | PstFrm.post_alpha := LeftStr( StripHTML( PstFrm.post_text) , 255 );
339 | PstFrm.post_size := IntToStr( Length ( PstFrm.post_text) );
340 | myPara.lastError := posts_Update( BrookFCLFCGIBroker.conn, PstFrm );
341 | if myPara.lastError <> '' then
342 | begin
343 | Render(err_page, ['Fehler beim Aktualisieren der Nachricht: ' + myPara.lastError]);
344 | exit;
345 | end;
346 |
347 | // refresh counters
348 | // update topic
349 | memTpc.views := sPlus( memTpc.views );
350 | memTpc.last_poster_id := PstFrm.post_edit_user ;
351 | memTpc.last_poster_name := usrFrm1.Name;
352 | memTpc.last_view_time := DateTimeToStr(now) ;
353 |
354 | myPara.lastError := Topic_Update( BrookFCLFCGIBroker.conn, memTpc );
355 | if myPara.lastError <> '' then
356 | begin
357 | Render(err_page, ['Fehler beim Aktualisieren des Themas: ' + myPara.lastError ]);
358 | exit;
359 | end;
360 |
361 | // update forum
362 | memFrm.last_poster_id := PstFrm.post_edit_user ;
363 | memFrm.last_poster_name := usrFrm1.Name;
364 | myPara.lastError := Upd_Forum( BrookFCLFCGIBroker.conn, memFrm );
365 | if myPara.lastError <> '' then
366 | begin
367 | Render(err_page, ['Fehler beim Aktualisieren des Forums: ' + myPara.lastError]);
368 | exit;
369 | end;
370 |
371 | redirect ('topic?ID=' + PstFrm.forum_id + '&Tpc=' + PstFrm.topic_id + '&sesn=' + myPara.VSession, 302);
372 | end;
373 |
374 |
375 | ///////////////////////////////////////////
376 | // Save changes to topic
377 | // Save old topic to log
378 | // Update forum's last use
379 | // finish with jump to post page
380 | procedure TChange.Tpc_Save ( VAR myPara: ParaType);
381 | VAR
382 | sTmp : string;
383 | memTpc : TopInfType ;
384 |
385 |
386 | begin
387 |
388 | // read topic
389 | memTpc.id := myPara.sTopic;
390 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
391 | if memTpc.id = '' then
392 | begin
393 | Render(err_page, ['Fehler beim Lesen des Themas: ' + myPara.sTopic]);
394 | exit;
395 | end;
396 |
397 | // update topic
398 | memTpc.views := sPlus( memTpc.views );
399 | memTpc.title := myPara.text1;
400 | memTpc.topic_text := myPara.text2;
401 | memTpc.last_view_time := DateTimeToStr(now);
402 | memTpc.last_post_time := memTpc.last_view_time;
403 |
404 | // save topic
405 | sTmp := Topic_Update( BrookFCLFCGIBroker.conn, memTpc );
406 | if sTmp <> '' then
407 | begin
408 | Render(err_page, ['Fehler beim Aktualisieren des Themas: ' + sTmp]);
409 | exit;
410 | end;
411 |
412 | // go to post page
413 | redirect ('topic?ID=' + memTpc.forum_id + '&Tpc=' + memTpc.id + '&sesn=' + myPara.VSession, 302);
414 |
415 |
416 | end;
417 |
418 | procedure TChange.Post;
419 | VAR
420 | myPara : ParaType;
421 |
422 | begin
423 |
424 | // check paras
425 | myPara.VSession := Fields.Values['sesn'];
426 | myPara.sTopic := Fields.Values['Tpc'];
427 | myPara.sPst := Fields.Values['Pst'];
428 | myPara.sID := Fields.Values['ID'];
429 | myPara.text1 := Fields.Values['tpc_name'];
430 | myPara.text2 := Fields.Values['S1'];
431 | myPara.sCmd := Fields.Values['B2'];
432 | myPara.sCmd += Fields.Values['B3'];
433 | myPara.sCmd += Fields.Values['B4']; // form post Button B2,B3 or B4
434 | mypara.sip := TheRequest.RemoteAddress;
435 | if NOT isSessionValid( mypara ) then
436 | begin
437 | Render(err_page, [myPara.LastError]);
438 | exit;
439 | end;
440 |
441 | case myPara.sCmd of
442 | 'chgtpc' : Tpc_Save ( myPara ); // change a topic
443 | 'chngpst' : Pst_Save ( myPara ); // show posting in bbs_editpst.html
444 | 'deltpst' : PstDelete( myPara ); // delete a posting
445 | else
446 | begin
447 | Render(err_page, ['Funktion fehlt oder unbekannt: ' + myPara.sCmd ]);
448 | exit;
449 | end;
450 | end;
451 |
452 |
453 | end;
454 |
455 | initialization
456 | TChange.Register('change');
457 |
458 | end.
459 |
460 |
--------------------------------------------------------------------------------
/dependencies.txt:
--------------------------------------------------------------------------------
1 | EasyBBS Fast-CGI Sample Requirements:
2 |
3 | Compile :
4 | Lazarus : > 1.2.0
5 | Synapse : 4.0
6 | Brook Framework : > 3.0
7 |
8 | Run
9 | DB & Designs : https://www.bergertime.eu/download/BBS_setup_de.zip
--------------------------------------------------------------------------------
/fevent.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 07.03.14
5 | // handle footer events
6 | // redirect to call page
7 | // sample href="/cgi-bin/bbs/event?ev=3&sesn=xxx
8 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
9 |
10 | unit fevent;
11 |
12 | {$mode objfpc}{$H+}
13 |
14 | interface
15 |
16 | uses
17 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
18 | FmtBCD, sqldb, blowcryp, mapping, menu;
19 |
20 | type
21 | Tfevent = class(TBrookAction)
22 | public
23 | procedure Get; override;
24 | end;
25 |
26 | implementation
27 |
28 | procedure Tfevent.Get;
29 | Var
30 | i : integer;
31 | sRedirect : String;
32 | sesnRec: sessInfType;
33 | myPara : ParaType;
34 |
35 |
36 | begin
37 | // build redirect string & read paras
38 | for I := 0 to Pred(Params.Count) do
39 | begin
40 | if sRedirect <> '' then sRedirect += '&';
41 | sRedirect += Params.Names[i] + '=' + Params.Values[Params.Names[i]]; // Params.Items[I].AsString;
42 | case Params.Names[i] of
43 | 'ev' : myPara.sPst := Params.Values['ev'];
44 | 'sesn' : myPara.VSession := Params.Values['sesn'];
45 | end
46 | end;
47 |
48 | mypara.sip:= TheRequest.RemoteAddress;
49 | if NOT isSessionValid( mypara ) then
50 | begin
51 | Render(err_page, [myPara.LastError]);
52 | exit;
53 | end;
54 |
55 | // read session info
56 | sesnRec.id := myPara.VSession;
57 | sesn_Read( BrookFCLFCGIBroker.conn, sesnRec);
58 |
59 | case myPara.sPst of
60 | '1' : sesnRec.v_order := '1'; // sort order
61 | '2' : sesnRec.v_order := '2';
62 | '3' : sesnRec.v_order := '3';
63 | '4' : if sesnRec.v_page <> '0' then sesnRec.v_page := sMinus( sesnRec.v_page ); // prev page
64 | '5' : if sesnRec.v_eof = '0' then sesnRec.v_page := sPlus ( sesnRec.v_page ); // next page
65 | end;
66 |
67 | myPara.LastError := sesn_update ( BrookFCLFCGIBroker.conn, sesnRec);
68 | if myPara.LastError <> '' then
69 | begin
70 | Render(err_page, [myPara.LastError]);
71 | exit;
72 | end;
73 |
74 | // return to caller
75 | redirect (sesnRec.forwarded_for + '&sesn=' + myPara.VSession, 302);
76 |
77 | end;
78 |
79 | initialization
80 | Tfevent.Register('event');
81 |
82 | end.
83 |
84 |
--------------------------------------------------------------------------------
/find.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 19.03.14
5 | // file : find.pas
6 | // search posts & topics
7 | // for user, headline, date or publish fulltext
8 |
9 | unit find;
10 |
11 | {$mode objfpc}{$H+}
12 |
13 | interface
14 |
15 | uses
16 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
17 | FmtBCD, mysql55conn, sqldb, blowcryp, mapping, menu;
18 |
19 |
20 | type
21 | Tfind = class(TBrookAction)
22 | public
23 | procedure Get; override;
24 | procedure Post; override;
25 | end;
26 |
27 | implementation
28 |
29 | //////////////////////////////////////////////////////////
30 | // validate bbs_find.html form entries
31 | // show error page on: all empty,
32 | // certain paras leading to empty result
33 | // otherwise : redirect to ./findrslt
34 |
35 | procedure Tfind.Post;
36 | var
37 | I : integer;
38 | mySessn: sessInfType;
39 | myPara : paraType;
40 | memFrm : ForInfType;
41 | memTpc : TopInfType;
42 | PstFrm : PstInfType;
43 | usrFrm1: usrInfType;
44 | query : TSQLQuery;
45 | sRslt, body, sDate : String;
46 |
47 | begin
48 |
49 | // read para
50 | for I := 0 to Fields.Count-1 do
51 | begin
52 | case Fields.Names[i] of
53 | 'sesn' : myPara.VSession := Fields.Values[Fields.Names[i]];
54 | 'Tpc' : myPara.sTopic := Fields.Values[Fields.Names[i]];
55 | 'user' : myPara.sID := Fields.Values[Fields.Names[i]];
56 | 'date' : myPara.sPst := Fields.Values[Fields.Names[i]];
57 | 'S1' : myPara.text2 := Fields.Values[Fields.Names[i]];
58 | 'B2' : myPara.sCmd := Fields.Values[Fields.Names[i]];
59 | 'B3' : myPara.sCmd := Fields.Values[Fields.Names[i]];
60 | end;
61 | end;
62 |
63 | // cancel on quit
64 | if myPara.sCmd = 'quit' then
65 | begin
66 | redirect ('main?sesn=' + myPara.VSession, 302);
67 | exit
68 | end;
69 |
70 | // cancel on unknown command
71 | if myPara.sCmd <> 'find' then
72 | begin
73 | Render(err_page, ['unknow command: ' + myPara.sCmd]);
74 | exit
75 | end;
76 |
77 | // exit on invalid session
78 | mypara.sip:= TheRequest.RemoteAddress;
79 | if NOT isSessionValid( mypara ) then
80 | begin
81 | Render(err_page, [myPara.lastError]);
82 | exit;
83 | end;
84 |
85 | // read session rec
86 | mySessn.id := mypara.VSession;
87 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
88 | sesn_copy_para( mySessn, myPara );
89 |
90 | // avoid code injection
91 | myPara.sTopic := SecuredStr(myPara.sTopic); // headline
92 | myPara.sID := SecuredStr(myPara.sID); // author
93 | myPara.sPst := SecuredStr(myPara.sPst); // publish date
94 | myPara.text2 := SecuredStr(myPara.text2); // medium blob text
95 |
96 |
97 | // exit on all empty
98 | if (myPara.sTopic = '') AND
99 | (myPara.sID = '' ) AND
100 | (myPara.sPst = '' ) AND
101 | (myPara.text2 = '' ) then
102 | begin
103 | Render(err_page, ['Keine Suchangaben ..']);
104 | exit;
105 | end;
106 |
107 | query := TSQLQuery.Create(nil);
108 | query.DataBase := BrookFCLFCGIBroker.conn;
109 |
110 | /////////////////////////////////
111 | // entry fields check queries
112 | sRslt := '';
113 | myPara.lastError := '';
114 |
115 | // search author
116 | if myPara.sID <> '' then
117 | begin
118 | // find user(s)
119 | sRslt := 'WHERE Name like "%' + myPara.sID + '%" ';
120 | query.SQL.Text := 'select * from user where name like "%' + myPara.sID +'%"' ;
121 | query.Open;
122 | if query.eof then myPara.lastError += 'Keine Author(en) gefunden: ' + myPara.sID + '';
123 | query.active := False;
124 | end;
125 |
126 | // search Headline in posts and topics - valid on any result
127 | if myPara.sTopic <> '' then
128 | begin
129 | sRslt += iif(sRslt='','WHERE ',' AND ') + '( post_subject like "%' + myPara.sTopic + '%" OR title like "%' + myPara.sTopic + '%" ) ';
130 | query.SQL.Text := 'SELECT * FROM posts where post_subject like "%' + myPara.sTopic + '%";';
131 | query.Open;
132 | if query.eof then
133 | begin
134 | query.active := False;
135 | query.SQL.Text := 'SELECT * FROM topics where title like "' + myPara.sTopic + '%";';
136 | query.Open;
137 | if query.eof then myPara.lastError += 'Kein Thema oder Nachricht mit Überschrift: ' + myPara.sTopic + '';
138 | end;
139 | query.active := False;
140 | end;
141 |
142 | // search Date in posts and topics - valid on any result
143 | if myPara.sPst <> '' then
144 | begin
145 | sDate := FormatDateTime('yyyy-mm-dd', StrToDate(myPara.sPst));
146 | sRslt += iif(sRslt='','WHERE ',' AND ') + 'post_time like "' + sDate +'%" ' ;
147 | query.SQL.Text := 'SELECT * FROM posts where post_time like "' + sDate + '%" OR post_edit_time like "' + sDate + '%";';
148 | query.Open;
149 | if query.eof then
150 | begin
151 | query.active := False;
152 | query.SQL.Text := 'SELECT * FROM topics where ctime like "' + sDate + '%" OR last_post_time like "' + sDate + '%";';
153 | query.Open;
154 | if query.eof then myPara.lastError += 'Keine Themen oder Nachrichten am: ' + sDate + '';
155 | end;
156 | query.active := False;
157 | end;
158 |
159 | // search text in blob
160 | if myPara.text2 <> '' then
161 | begin
162 | myPara.text2 := StripHTML( myPara.text2 );
163 | sRslt += iif(sRslt='','WHERE ',' AND ') + 'match(post_text) AGAINST ("' + myPara.text2 + '" IN NATURAL LANGUAGE MODE) ';
164 | query.SQL.Text := 'select * from posts where match ( post_text ) AGAINST (''' + myPara.text2 + ''' IN NATURAL LANGUAGE MODE);';
165 | query.Open;
166 | if query.eof then myPara.lastError += 'Keine Nachricht mit Inhalt: ' + myPara.text2 ;
167 | query.active := False;
168 | end;
169 |
170 | sRslt := 'SELECT * from find ' + sRslt;
171 |
172 | // exit if one search para leads to empty result
173 | if myPara.lastError <> '' then
174 | begin
175 | query.Free;
176 | Render(err_page, [myPara.lastError]);
177 | exit;
178 | end;
179 |
180 |
181 | //////////////////////
182 | // main query
183 | query.SQL.Text := sRslt;
184 | query.Open;
185 |
186 | // exit if combined paras leads to empty result
187 | if query.eof then
188 | begin
189 | sRslt := sUpdate( findinfo,'%%5', myPara.sTopic + '. ');
190 | sRslt := sUpdate( sRslt, '%%6', myPara.sID + '. ');
191 | sRslt := sUpdate( sRslt, '%%7', myPara.sPst + '. ');
192 | sRslt := sUpdate( sRslt, '%%8', myPara.text2 + '. ');
193 | Render(err_page, ['Keine Ergebnisse für ' + sRslt]);
194 | query.active := False;
195 | query.Free;
196 | exit;
197 | end;
198 |
199 | // update session rec with blob search
200 | mySessn.lastsearch:= myPara.text2 ;
201 | sesn_update( BrookFCLFCGIBroker.conn, mySessn );
202 |
203 | // open find result
204 | redirect ('frslt?ID=' + myPara.sID + '&Tpc=' + myPara.sTopic +
205 | '&Pst=' + myPara.sPst + '&sesn=' + myPara.VSession,
206 | 302);
207 |
208 | // release mem
209 | query.active := False;
210 | query.Free;
211 |
212 |
213 | end;
214 |
215 | //////////////////////////////////////////////////////////
216 | // render bbs_find.html form
217 | // add session info to header & footer
218 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
219 |
220 | procedure Tfind.Get;
221 | var
222 | I : integer;
223 | sMenu : String;
224 | mySessn: sessInfType;
225 | myPara : paraType;
226 |
227 |
228 | begin
229 | // check session
230 | mypara.VSession := Params.Values['sesn'];
231 | mypara.sip:= TheRequest.RemoteAddress;
232 | if NOT isSessionValid( mypara ) then
233 | begin
234 | Render(err_page, [myPara.lastError]);
235 | exit;
236 | end;
237 |
238 | // callback target
239 | paraTypeInit('find?', myPara ); // init mypara
240 | mypara.sCmd := '1'; // '1' full header menu
241 | mySessn.id := mypara.VSession;
242 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
243 | sesn_copy_para( mySessn, myPara );
244 |
245 | sMenu := make_header(mypara);
246 | mypara.sCmd := '0'; // no nav or search in footer
247 |
248 | // display
249 | Render('bbs_find.html', [ sMenu,
250 | mypara.VSession,
251 | make_footer( BrookFCLFCGIBroker.conn, mypara)]);
252 |
253 |
254 | end;
255 |
256 | initialization
257 | Tfind.Register('find');
258 |
259 | end.
260 |
261 |
--------------------------------------------------------------------------------
/forums.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 11.02.14
5 | // file : forums.pas
6 | // modified : 12.03.14
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 | // called via: 'cgi1/forum?ID=XXXX&sesn=XXXXXXXXXXXXXXX'
9 |
10 | unit forums;
11 |
12 | {$mode objfpc}{$H+}
13 |
14 | interface
15 |
16 | uses
17 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
18 | FmtBCD, sqldb, mapping, blowcryp, menu;
19 |
20 | type
21 | TForum = class(TBrookAction)
22 | public
23 | procedure Get; override;
24 | end;
25 |
26 |
27 | implementation
28 |
29 |
30 | procedure TForum.Get;
31 | var
32 | i : integer;
33 | sBody, sLink, sInfo, sTmp : string;
34 | memFrm : ForInfType;
35 | memTpc : TopInfType;
36 | mypara : ParaType;
37 | mySessn: sessInfType;
38 | query : TSQLQuery;
39 |
40 |
41 |
42 | begin
43 | // check paras
44 | memTpc.forum_id := Params.Values['ID'];
45 | mypara.VSession := Params.Values['sesn'];
46 | if memTpc.forum_id = '' then
47 | begin
48 | Render(err_page, ['Forum ID fehlt.' ]);
49 | exit;
50 | end;
51 | mypara.sip:= TheRequest.RemoteAddress;
52 | if NOT isSessionValid( mypara ) then
53 | begin
54 | Render(err_page, [mypara.lastError]);
55 | exit;
56 | end;
57 |
58 | // read session record
59 | paraTypeInit('forum?', myPara ); // preset myPara
60 | mySessn.id := mypara.VSession;
61 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
62 | sesn_copy_para( mySessn, myPara );
63 |
64 | // set display order
65 | case myPara.v_order of
66 | '0' : sTmp := '' ;
67 | '1' : sTmp := ' ORDER BY last_post_time';
68 | '2' : sTmp := ' ORDER BY views';
69 | '3' : sTmp := ' ORDER BY title';
70 | end;
71 |
72 | // read forum info
73 | ReadForum( BrookFCLFCGIBroker.conn, 'where id=' + memTpc.forum_id, memFrm );
74 |
75 | // query
76 | query := TSQLQuery.Create(nil);
77 | query.DataBase := BrookFCLFCGIBroker.conn;
78 | query.SQL.Text := 'SELECT * FROM topics where forum_id=' +
79 | memTpc.forum_id + // parent forum
80 | sTmp + // order by
81 | ' limit ' + // limit start,stop
82 | IntToStr( StrToInt( myPara.v_page ) * PageItems )
83 | + ',' + IntToStr( StrToInt( myPara.v_page ) * PageItems + PageItems+1 );
84 | query.Open;
85 |
86 | // loop through records til limit
87 | // we set limit+1 to use query.eof for navibar handler
88 | i := 0;
89 | while not query.EOF do
90 | begin
91 | sTmp := '' + #13;
93 |
94 | // sLink sample : erstes Topic
95 | // &page=0 used in /topic to reset session.vpage
96 | sLink := ' ' +
99 | query.FieldByName('title').asString + ' ' +
100 | LEFTSTR ( query.FieldByName('topic_text').asString, 120) + ' .. ' ;
101 | sTmp := sUpdate ( sTmp, '%%0', sLink ); // para %%0 : title
102 |
103 | // sInfo sample : von: Kleeblatt am: 30.12.2013 Hits: 0 Posts: 0
104 | sInfo := ' erstellt von: ' + query.FieldByName('poster_name').asString +
105 | ' am: ' + query.FieldByName('ctime').asString +
106 | ' Zugriffe: ' + query.FieldByName('views').asString +
107 | ' Antworten: ' + query.FieldByName('replies').asString;
108 | sTmp := sUpdate ( sTmp, '%%1', sInfo ); // para %%1 : info
109 | sBody += sTmp;
110 | i += 1;
111 | if i = PageItems then break;
112 | query.next;
113 | end;
114 |
115 | // build mypara for header & footer menus
116 | mypara.sCmd := '1'; // '1' full record
117 | myPara.v_eof := iif( query.EOF, '1', '0'); // eof flag
118 | mypara.V_rec := query.FieldByName('id').asString; // last recid
119 | mypara.Text1 := 'forum?ID=' + memTpc.forum_id; // saved in session.forward_for
120 | mypara.sID := memTpc.forum_id ; // Header Menu Para
121 | mypara.sTopic:= memFrm.fName ; // Header Menu Text
122 |
123 | // display
124 | Render('bbs_topic.html', [make_Header_newThm(mypara),
125 | sBody,
126 | make_Footer( BrookFCLFCGIBroker.conn, mypara )]) ;
127 |
128 | // release db
129 | query.active := false;
130 | query.free;
131 |
132 | end;
133 |
134 |
135 |
136 | initialization
137 | TForum.Register('forum');
138 | end.
139 |
140 |
--------------------------------------------------------------------------------
/frslt.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 20.03.14
5 | // file : frslt.pas
6 | // list posts & topics results from find.pas as table
7 | // use template bbs_findrslt.html
8 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
9 |
10 | unit frslt;
11 |
12 | {$mode objfpc}{$H+}
13 |
14 | interface
15 |
16 | uses
17 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
18 | FmtBCD, sqldb, blowcryp, mapping, menu;
19 |
20 |
21 | type
22 | Tfrslt = class(TBrookAction)
23 | public
24 | procedure Get; override;
25 | end;
26 |
27 | implementation
28 |
29 | procedure Tfrslt.Get;
30 | var
31 | i : integer;
32 | sRslt, body, sDate : String;
33 | mySessn: sessInfType;
34 | myPara : paraType;
35 | query : TSQLQuery;
36 |
37 | begin
38 |
39 | // read paras
40 | myPara.VSession := Params.Values['sesn'];
41 | myPara.sID := Params.Values['ID'];
42 | myPara.sTopic := Params.Values['Tpc'];
43 | myPara.sPst := Params.Values['Pst'];
44 | // check session timeout
45 | mypara.sip:= TheRequest.RemoteAddress;
46 | if NOT isSessionValid( mypara ) then
47 | begin
48 | Render(err_page, ['session timeout ' + myPara.lastError + myPara.VSession + inttostr(i) ]);
49 | exit;
50 | end;
51 |
52 |
53 | // get session info
54 | paraTypeInit('frslt?', myPara ); // init mypara
55 | mypara.sCmd := '1'; // '1' full menus
56 | mySessn.id := mypara.VSession; // read session rec
57 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
58 | sesn_copy_para( mySessn, myPara );
59 | myPara.text1 := 'frslt?ID=' + myPara.sID + // add search paras
60 | '&Tpc=' + myPara.sTopic +
61 | '&Pst=' + myPara.sPst +
62 | '&sesn=' + myPara.VSession;
63 | myPara.text2 := mySessn.lastsearch; // blob search from session rec
64 |
65 |
66 | // build query
67 | if myPara.sID <>'' then sRslt += 'WHERE Name like "%' + myPara.sID + '%" ';
68 | if myPara.sTopic<>'' then sRslt += iif(sRslt='','WHERE ',' AND ') + '( post_subject like "%' + myPara.sTopic + '%" OR title like "%' + myPara.sTopic + '%" ) ';
69 | if myPara.sPst <>'' then sRslt += iif(sRslt='','WHERE ',' AND ') + 'post_time like "' + FormatDateTime('yyyy-mm-dd', StrToDate(myPara.sPst)) +'%" ' ;
70 | if myPara.text2 <>'' then sRslt += iif(sRslt='','WHERE ',' AND ') + 'match(post_text) AGAINST ("' + myPara.text2 + '" IN NATURAL LANGUAGE MODE) ';
71 | sRslt := 'SELECT * from find ' + sRslt;
72 |
73 | // set display order
74 | case myPara.v_order of
75 | '1' : sRslt += ' ORDER BY post_time';
76 | '2' : sRslt += ' ORDER BY iduser';
77 | '3' : sRslt += ' ORDER BY forum_id';
78 | end;
79 |
80 | // set limit ( start,stop )
81 | sRslt += ' limit ' +
82 | IntToStr( StrToInt( myPara.v_page ) * PageItems ) + ',' +
83 | IntToStr( StrToInt( myPara.v_page ) * PageItems + PageItems+1 );
84 |
85 | //////////////////////
86 | // main query
87 | query := TSQLQuery.Create(nil);
88 | query.DataBase := BrookFCLFCGIBroker.conn;
89 | query.SQL.Text := sRslt;
90 | query.Open;
91 |
92 | i := 0;
93 | body := '';
94 | while not query.EOF do
95 | begin
96 | sRslt := sUpdate(findrslt,'%%1','' +
98 | query.FieldByName('fname').AsString + ' ' );
99 | sRslt := sUpdate( sRslt, '%%2','' +
102 | query.FieldByName('title').AsString + ' ' );
103 | sRslt := sUpdate( sRslt, '%%3',StripHTML( query.FieldByName('post_text').AsString) );
104 | sRslt := sUpdate( sRslt, '%%4','' +
106 | query.FieldByName('Name').AsString + ' ' );
107 | body += sRslt;
108 | i += 1;
109 | if i = PageItems then break;
110 | query.next;
111 | end;
112 |
113 | // Build last table line
114 | // display blanks as ..
115 | sRslt := sUpdate( findinfo, '%%5', iif( myPara.sTopic='', '..', myPara.sTopic));
116 | sRslt := sUpdate( sRslt, '%%6', iif( myPara.sID ='', '..', myPara.sID));
117 | sRslt := sUpdate( sRslt, '%%7', iif( myPara.sPst ='', '..', myPara.sPst));
118 | sRslt := sUpdate( sRslt, '%%8', iif( myPara.text2 ='', '..', myPara.text2));
119 | body += sRslt;
120 |
121 | // set footer info
122 | myPara.v_eof := iif( query.EOF, '1', '0'); // eof flag
123 |
124 | // show page
125 | Render('bbs_findrslt.html', [ make_header(mypara), // header
126 | body, // body
127 | make_footer( BrookFCLFCGIBroker.conn, mypara) ]); // footer
128 | // release mem
129 | query.active := False;
130 | query.Free;
131 |
132 | end;
133 |
134 | initialization
135 | Tfrslt.Register('frslt');
136 |
137 | end.
138 |
139 |
--------------------------------------------------------------------------------
/geoinfo.pas:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // file : geoinfo.pas
4 | // created : 07.05.14
5 | // function : show active bbs users on google maps
6 | // called via: bbs/geoinfo
7 | // paras : s1 = latlon positions, s2 = marker, s3 = boundary elements
8 | // s4 = header, s5 = footer
9 |
10 | unit geoinfo;
11 | {$mode objfpc}{$H+}
12 |
13 | interface
14 |
15 | uses
16 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
17 | FmtBCD, sqldb, blowcryp, mapping, menu;
18 |
19 | CONST
20 |
21 | sPos = 'var <> = new google.maps.LatLng(<>, <>);' + #13;
22 | sMark = 'var <> = new google.maps.Marker({ position: <>, map: map, title: ''<>'' });' + #13;
23 | sBound = 'Bounds.extend(<>);' + #13 ;
24 |
25 |
26 | type
27 | Tgeoinfo = class(TBrookAction)
28 | public
29 | procedure Get; override;
30 | end;
31 |
32 | implementation
33 |
34 | procedure Tgeoinfo.Get;
35 | var
36 | i : integer;
37 | poscalc : extended;
38 |
39 | myPos, myMark, myBound,
40 | tPos, tMark, tBound,
41 | myLat, myLon : String;
42 |
43 | mypara : paraType;
44 | usrFrm1: usrInfType;
45 | mySessn: sessInfType;
46 | query : TSQLQuery;
47 |
48 | begin
49 |
50 | // check session
51 | mypara.VSession := Params.Values['sesn'];
52 | mypara.sip:= TheRequest.RemoteAddress;
53 | if NOT isSessionValid( mypara ) then
54 | begin
55 | Render(err_page, [myPara.lastError]);
56 | exit;
57 | end;
58 |
59 | // preset myPara
60 | paraTypeInit('geoinfo?', myPara ); // callback target for footer
61 | mypara.sCmd := '1'; // '1' full menus
62 | mySessn.id := mypara.VSession;
63 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
64 | sesn_copy_para( mySessn, myPara );
65 |
66 | // query
67 | query := TSQLQuery.Create(nil);
68 | query.DataBase := BrookFCLFCGIBroker.conn;
69 | query.SQL.Text := 'select * from sessions where is_active = 1;';
70 | query.Open;
71 |
72 | if query.EOF then
73 | begin
74 | query.active := false;
75 | query.free;
76 | Render(err_page, ['No Users online.']);
77 | exit;
78 | end;
79 |
80 | // loop throug open sessions
81 | i := 1;
82 | while not query.EOF do
83 | begin
84 | cpySessInfo ( query, mySessn );
85 | // read session user
86 | ReadUsr( conn, 'where iduser=' + mySessn.user_id , usrFrm1 );
87 |
88 | // get best lat/lon
89 | /// lat
90 | if (Length(mySessn.longitude) > Length(mySessn.sLong)) then
91 | poscalc := StrToFloat(mySessn.longitude)
92 | else
93 | poscalc := StrToFloat(mySessn.sLong);
94 | poscalc := poscalc + i * 0.000007; // avoid stacks on map
95 | myLon := FloatToStr( poscalc );
96 | /// lat
97 | if (Length(mySessn.latitude) > Length(mySessn.sLat)) then
98 | poscalc := StrToFloat(mySessn.latitude)
99 | else
100 | poscalc := StrToFloat(mySessn.sLat);
101 | poscalc := poscalc + i * 0.000007; // avoid stacks on map
102 | myLat := FloatToStr( poscalc );
103 |
104 | // build java script inserts
105 | myPos := sUpdate( sPos, '<>', 'pos' + IntToStr(i) ); // set var name
106 | myPos := sUpdate( myPos, '<>', sUpdate(myLat, ',','.')); // set vars lat
107 | myPos := sUpdate( myPos, '<>', sUpdate(myLon, ',', '.')); // set vars lon
108 | tPos += myPos;
109 |
110 | myMark := sUpdate( sMark, '<>', 'mark' + IntToStr(i) ); // set marker name
111 | myMark := sUpdate( myMark, '<>', 'pos' + IntToStr(i) ); // set var name
112 | myMark := sUpdate( myMark, '<>', usrFrm1.Name ); // set marker info
113 | tMark += myMark;
114 |
115 | myBound:= sUpdate( sBound, '<>', 'pos' + IntToStr(i) ); // set boundary
116 | tBound += myBound;
117 | i += 1;
118 | query.Next;
119 | end;
120 |
121 |
122 | // display geo_pos
123 | Render('bbs_geopos.html', [tPos, tMark, tBound,
124 | make_Header( mypara ),
125 | make_Footer( BrookFCLFCGIBroker.conn, mypara ) ]);
126 |
127 | // release mem
128 | query.active := false;
129 | query.free;
130 |
131 |
132 | end;
133 |
134 |
135 | initialization
136 | Tgeoinfo.Register('geoinfo');
137 |
138 | end.
139 |
140 |
--------------------------------------------------------------------------------
/info.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 01.03.14
5 | // list active users
6 | // show info tiles ( total , logins, href to user posts( upst )
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 |
9 | unit info;
10 |
11 | {$mode objfpc}{$H+}
12 |
13 | interface
14 |
15 | uses
16 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
17 | FmtBCD, strutils, sqldb, blowcryp, mapping, menu;
18 |
19 | type
20 | TInfo = class(TBrookAction)
21 | public
22 | procedure Get; override;
23 | end;
24 |
25 | implementation
26 |
27 | procedure TInfo.Get;
28 | var
29 | I : Integer;
30 | sTiles, kachel, sTmp : string;
31 | usrFrm1: usrInfType;
32 | mySessn: sessInfType;
33 | myPara : paraType;
34 | query : TSQLQuery;
35 |
36 |
37 | begin
38 | // check session
39 | mypara.VSession := Params.Values['sesn'];
40 | mypara.sip:= TheRequest.RemoteAddress;
41 | if NOT isSessionValid( mypara ) then
42 | begin
43 | Render(err_page, [myPara.lastError]);
44 | exit;
45 | end;
46 |
47 |
48 | // callback target
49 | paraTypeInit('info?', myPara ); // init mypara
50 | mypara.sCmd := '1'; // '1' full menus
51 | mySessn.id := mypara.VSession;
52 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
53 | sesn_copy_para( mySessn, myPara );
54 |
55 | // set display order
56 | case myPara.v_order of
57 | '0' : sTmp := '' ;
58 | '1' : sTmp := ' ORDER BY login';
59 | '2' : sTmp := ' ORDER BY latitude, longitude';
60 | '3' : sTmp := ' ORDER BY user_id';
61 | end;
62 |
63 |
64 | // query
65 | query := TSQLQuery.Create(nil);
66 | query.DataBase := BrookFCLFCGIBroker.conn;
67 | query.SQL.Text := 'select * from sessions where is_active = 1' +
68 | sTmp + // order by
69 | ' limit ' + // limit start,stop
70 | IntToStr( StrToInt( myPara.v_page ) * PageItems )
71 | + ',' + IntToStr( StrToInt( myPara.v_page ) * PageItems + PageItems+1 );
72 | query.Open;
73 |
74 | if query.EOF then
75 | begin
76 | query.active := false;
77 | query.free;
78 | Render(err_page, ['No Users online.']);
79 | exit;
80 | end;
81 |
82 | // loop throug open sessions
83 | i := 0;
84 | sTiles := '';
85 | while not query.EOF do
86 | begin
87 | cpySessInfo ( query, mySessn );
88 | // read session user
89 | ReadUsr( conn, 'where iduser=' + mySessn.user_id , usrFrm1 );
90 | // set user tile
91 | kachel := sUpdate( usrTile,'%%0', mySessn.user_id ); // UserID
92 | kachel := sUpdate( kachel, '%%1', iif((i mod 2=1),'rkachel','bkachel')); // tile(red/blue)
93 | kachel := sUpdate( kachel, '%%2', usrFrm1.Name ); // UserName
94 | kachel := sUpdate( kachel, '%%3', showUsrImage(usrFrm1)); // User PNG
95 | kachel := sUpdate( kachel, '%%4', MIDSTR(mySessn.login,12,5)); // Session start ( HH:MM )
96 | kachel := sUpdate( kachel, '%%5', usrFrm1.TotalTime ); // User logins
97 | kachel := sUpdate( kachel, '%%6', myPara.VSession ); // Session ID
98 | sTiles += kachel;
99 | i += 1;
100 | if i = PageItems then break;
101 | query.Next;
102 | end;
103 |
104 | // prepare & render
105 | // Update Session info
106 | myPara.v_rec := mySessn.rid; // last rec in display
107 | myPara.v_eof := iif( query.EOF, '1', '0'); // eof flag
108 |
109 | Render('bbs_onln.html', [ make_header(mypara),
110 | sTiles,
111 | make_footer( BrookFCLFCGIBroker.conn, mypara)]);
112 |
113 | // release mem
114 | query.active := false;
115 | query.free;
116 |
117 | end;
118 |
119 | initialization
120 | TInfo.Register('info');
121 |
122 | end.
123 |
124 |
--------------------------------------------------------------------------------
/legal.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 02.03.14
5 | // render forms : bbs_terms.html, bbs_imprint.html, bbs_privacy.html
6 | // select via : legal?actn=1,2,3
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 |
9 | unit legal;
10 |
11 | {$mode objfpc}{$H+}
12 |
13 | interface
14 |
15 | uses
16 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
17 | FmtBCD, sqldb, blowcryp, mapping, menu;
18 |
19 | type
20 | TLegal = class(TBrookAction)
21 | public
22 | procedure Get; override;
23 | end;
24 |
25 | implementation
26 |
27 | procedure TLegal.Get;
28 | var
29 |
30 | bSessn : boolean;
31 | sActn : String;
32 | myPara : ParaType;
33 | mySessn : sessInfType;
34 | sMenu, sFooter : string;
35 |
36 |
37 | begin
38 |
39 | sActn := Params.Values['actn'];
40 | mypara.VSession := Params.Values['sesn'];
41 | if sActn = '' then
42 | begin
43 | Render(err_page, ['Action ID fehlt.']);
44 | exit;
45 | end;
46 |
47 | // no break on expired session - always render legal forms
48 | mypara.sip:= TheRequest.RemoteAddress;
49 | bSessn:= isSessionValid( mypara ) ;
50 |
51 | // preset myPara
52 | paraTypeInit('legal?actn=' + sActn, myPara );
53 |
54 | // read session record
55 | if bSessn then
56 | begin
57 | mySessn.id := mypara.VSession;
58 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
59 | sesn_copy_para( mySessn, myPara );
60 | end;
61 |
62 | mypara.sCmd := iif ( bSessn, '1', '0');
63 |
64 | sMenu := make_Header( mypara );
65 | sFooter := make_Footer( BrookFCLFCGIBroker.conn, mypara );
66 | if mypara.lastError <> '' then
67 | begin
68 | Render(err_page, [mypara.lastError]);
69 | exit;
70 | end;
71 |
72 | // render template
73 | case sActn of
74 | '1' : Render('bbs_terms.html', [ sMenu, GetContent( BrookFCLFCGIBroker.conn, 'AGB'), sFooter ]);
75 | '2' : Render('bbs_terms.html', [ sMenu, GetContent( BrookFCLFCGIBroker.conn, 'Privacy'), sFooter ]);
76 | '3' : Render('bbs_terms.html', [ sMenu, GetContent( BrookFCLFCGIBroker.conn, 'Imprint'), sFooter ]);
77 | else
78 | Render(err_page, ['Action ID unbekannt:' + sActn +'.']);
79 | end;
80 |
81 | end;
82 |
83 | initialization
84 | TLegal.Register('legal');
85 |
86 | end.
87 |
88 |
89 |
--------------------------------------------------------------------------------
/logout.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 01.03.14
5 | // file : Logout.pas
6 | // close session record
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 |
9 | unit Logout;
10 |
11 | {$mode objfpc}{$H+}
12 |
13 | interface
14 |
15 | uses
16 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
17 | FmtBCD, sqldb, blowcryp, mapping, menu;
18 |
19 | type
20 | TGoodBye = class(TBrookAction)
21 | public
22 | procedure Get; override;
23 | end;
24 |
25 | implementation
26 |
27 | procedure TGoodBye.Get;
28 | var
29 | SessRec: sessInfType;
30 | myPara : ParaType;
31 |
32 | begin
33 | // check session
34 | myPara.VSession := Params.Values['sesn'];
35 | mypara.sip:= TheRequest.RemoteAddress;
36 | if NOT isSessionValid( mypara ) then
37 | begin
38 | redirect ('./main?',302);
39 | exit;
40 | end;
41 |
42 | // close session
43 | SessRec.user_id := IntToStr( myPara.userID );
44 | sesn_close( BrookFCLFCGIBroker.conn, SessRec );
45 |
46 | // free mem
47 | redirect ('./main?',302);
48 |
49 | end;
50 |
51 | initialization
52 | TGoodBye.Register('quit');
53 |
54 | end.
55 |
56 |
--------------------------------------------------------------------------------
/main.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 08.05.14
5 | // file : main.pas
6 | // called via: cgi1/main?sesn=xx
7 | // or: cgi1/main for login dialog
8 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
9 | // : 27.04.14 - change para read
10 |
11 | unit main;
12 |
13 | {$mode objfpc}{$H+}
14 |
15 | interface
16 |
17 | uses
18 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
19 | FmtBCD, sqldb, blowcryp, mapping, menu;
20 |
21 | type
22 | TWelcome = class(TBrookAction)
23 | public
24 | procedure Get; override;
25 | procedure Post; override;
26 | end;
27 |
28 |
29 | implementation
30 |
31 | procedure TWelcome.Post;
32 | var
33 | VUser, VPass, VCmd, sTmp : string;
34 | usrRec : usrInfType;
35 | sesnRec : sessInfType;
36 |
37 |
38 | begin
39 |
40 | // post w/o paras? -> only refresh main page ( not logged in )
41 | if Fields.Count = 0 then
42 | begin
43 | redirect ('./main?',302);
44 | exit;
45 | end;
46 |
47 | // copy paras
48 | VUser := SecuredStr(Fields.Values['usr'] );
49 | VPass := SecuredStr(Fields.Values['pwd'] );
50 | VCmd := SecuredStr(Fields.Values['btn'] );
51 | sesnRec.latitude := Fields.Values['lat'];
52 | sesnRec.longitude := Fields.Values['lon'];
53 | sesnRec.accuracy := Fields.Values['acc'];
54 |
55 |
56 | // check paras
57 | if (VCmd = 'Anmelden') then
58 | begin
59 | if ( VUser = '' ) OR ( VPass = '' ) then
60 | begin
61 | Render(err_page, ['Username oder Passwort dürfen nicht leer sein.']);
62 | exit;
63 | end;
64 | end;
65 |
66 | if (VCmd = 'Abbrechen') then
67 | begin
68 | redirect ('./main?',302);
69 | exit;
70 | end;
71 |
72 | if (VCmd = 'neues Konto') then
73 | begin
74 | redirect ('./accnt?',302);
75 | exit;
76 | end;
77 |
78 |
79 | ReadUsr( BrookFCLFCGIBroker.conn, 'where name = "' + VUser +'"', usrRec );
80 | if usrRec.name = '' then
81 | begin
82 | Render(err_page, ['Username unbekannt']);
83 | exit;
84 | end;
85 |
86 | // check pwd
87 | if usrRec.pwd <> TRIM( VPass ) then
88 | begin
89 | Render(err_page, ['Falsches PWD']);
90 | exit;
91 | end;
92 |
93 | // check registration
94 | if usrRec.isChecked <> 'True' then
95 | begin
96 | Render(err_page, ['Account nicht aktiviert.']);
97 | exit;
98 | end;
99 |
100 | // update user record
101 | usrRec.picture_png := ''; // avoid blob save -> speed up
102 | usrRec.TotalTime := sPlus(usrRec.TotalTime); // incr login count
103 | sesnRec.lastlogin := usrRec.LastTime; // rescue old LastLogin
104 | usrRec.LastTime := DateTimeToStr( now ); // set login time
105 | sTmp := updUser( BrookFCLFCGIBroker.conn, usrRec );
106 | if sTmp <> '' then
107 | begin
108 | Render(err_page, [ sTmp ]);
109 | exit;
110 | end;
111 |
112 | // add session record
113 | sesnRec.browser := TheRequest.UserAgent;
114 | sesnRec.sip := TheRequest.RemoteAddress;
115 | sesnRec.user_id := usrRec.iduser; // add user_id
116 | codeSessionID( sesnRec ); // create sesnRec.id
117 | sesnRec.is_active := '1'; // active = true
118 | sesnRec.last_forum := sesnRec.forum_id ; //
119 | sesnRec.forum_id := '0';
120 | sesnRec.forwarded_for:= 'main?sesn=' + sesnRec.id;
121 | sesnRec.v_page := '0';
122 | sesnRec.v_rec := '1';
123 | sesnRec.v_order := '1';
124 | sesnRec.v_eof := '0';
125 | sesnRec.last_post_cnt:= posts_Count( BrookFCLFCGIBroker.conn, sesnRec.lastlogin );
126 | GetIPLatLon( GetSetting( BrookFCLFCGIBroker.conn,'GeoIP') + sesnRec.sip,
127 | sesnRec.sLat, sesnRec.sLong );
128 |
129 | sTmp := sesn_insert ( BrookFCLFCGIBroker.conn, sesnRec);
130 | if sTmp <> '' then
131 | begin
132 | Render(err_page, [sTmp]);
133 | exit;
134 | end;
135 |
136 | // show homepage
137 | redirect ( './main?sesn=' + sesnRec.id, 302 );
138 |
139 | end;
140 |
141 | { TWelcome }
142 | procedure TWelcome.Get;
143 | var
144 | i : integer;
145 | sTiles, Kachel, sTmp : string;
146 | bSessn : boolean;
147 | myPara : ParaType;
148 | memQry : ForInfType;
149 | mySessn : sessInfType;
150 | query : TSQLQuery;
151 |
152 | begin
153 |
154 | // check session
155 | myPara.VSession := Params.Values['sesn'];
156 | mypara.sip:= TheRequest.RemoteAddress;
157 | bSessn:= isSessionValid( mypara );
158 |
159 | // preset myPara
160 | paraTypeInit('main?', myPara );
161 | // read session record
162 | if bSessn then
163 | begin
164 | mySessn.id := mypara.VSession;
165 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
166 | sesn_copy_para( mySessn, myPara );
167 | end;
168 |
169 | // set display order
170 | case myPara.v_order of
171 | '0' : sTmp := '' ;
172 | '1' : sTmp := ' ORDER BY last_post_time';
173 | '2' : sTmp := ' ORDER BY posts';
174 | '3' : sTmp := ' ORDER BY fname';
175 | end;
176 |
177 | // query
178 | query := TSQLQuery.Create(nil);
179 | query.DataBase := BrookFCLFCGIBroker.conn;
180 | query.SQL.Text := 'select * from forums' +
181 | sTmp + // order by
182 | ' limit ' + // limit start,stop
183 | IntToStr( StrToInt( myPara.v_page ) * PageItems )
184 | + ',' + IntToStr( StrToInt( myPara.v_page ) * PageItems + PageItems+1 );
185 | query.Open;
186 | if query.EOF then
187 | begin
188 | query.active := false;
189 | query.free;
190 | Render(err_page, ['No Forums!']);
191 | exit;
192 | end;
193 |
194 | // generate tiles
195 | i := 0;
196 | sTiles := '';
197 | while not query.EOF do
198 | begin
199 | cpyForumInfo( Query, memQry );
200 | kachel := iif(bSessn,
201 | sUpdate ( tpcTile, '%%6', cgiPath + 'forum?ID=%%0&sesn=' + myPara.VSession ) ,
202 | sUpdate ( tpcTile, '%%6', '#" onclick="overlay()') ); // set link
203 | kachel := sUpdate( kachel, '%%0', memQry.id ); // ForumID
204 | kachel := sUpdate( kachel, '%%1', iif((i mod 2=1),'rkachel','bkachel')); // red/blue tile
205 | kachel := sUpdate( kachel, '%%2', memQry.fname ); // ForumName
206 | kachel := sUpdate( kachel, '%%3', memQry.fdesc ); // Forum Description
207 | kachel := sUpdate( kachel, '%%4', LEFTSTR(memQry.last_post_time,6) ); // Last post ( DD.MM )
208 | kachel := sUpdate( kachel, '%%5', memQry.topics ); // topics#
209 | sTiles += kachel;
210 | i += 1;
211 | if i = PageItems then break;
212 | query.Next;
213 | end;
214 |
215 |
216 | // Update Session info
217 | myPara.v_rec := memQry.id; // last rec in display
218 | myPara.Text1 := 'main?'; // callback target for footer
219 | myPara.v_eof := iif( query.EOF, '1', '0'); // eof flag
220 | mypara.sCmd := iif( bSessn, '1', '0'); // if session full menu else pre login menu
221 |
222 | // render
223 | Render('bbs_main.html', [ make_Header( mypara ),
224 | sTiles,
225 | make_Footer( BrookFCLFCGIBroker.conn, mypara ) ]);
226 |
227 | // release mem
228 | query.active := false;
229 | query.free;
230 |
231 | end;
232 |
233 |
234 | initialization
235 | TWelcome.Register('main');
236 |
237 | end.
238 |
--------------------------------------------------------------------------------
/mapping.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : by schema mapper V. 2.1 - 28.02.14
5 | // file : mapping.pas
6 | // created : 28.02.14
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 | // 04.05.2014 Update Commit for Laz. 1.2.2
9 | // 08.05.2014 blob save as hexstr
10 | // tested : yes
11 |
12 | unit Mapping;
13 |
14 | {$mode objfpc}{$H+}
15 |
16 | interface
17 |
18 | uses
19 | Classes, SysUtils, Variants, FmtBCD, mysql55conn, sqldb, blowcryp ;
20 |
21 | const
22 | sqlDate = 'yyyy-mm-dd hh:nn:ss';
23 |
24 |
25 | type
26 | ForInfType = record // forums record
27 | id: string;
28 | fName: string;
29 | fDesc: string;
30 | fdesc_bitfield: string;
31 | fdesc_uid: string;
32 | topics_per_page: string;
33 | posts: string;
34 | topics: string;
35 | topics_real: string;
36 | last_post_id: string;
37 | last_poster_id: string;
38 | last_post_subject: string;
39 | last_post_time : string;
40 | last_poster_name: string;
41 | end;
42 |
43 | TopInfType = record // topics record
44 | id : string;
45 | forum_id : string;
46 | title : string;
47 | topic_text : string;
48 | poster : string;
49 | poster_name : string;
50 | ctime : string;
51 | time_limit : string;
52 | views : string;
53 | replies : string;
54 | replies_real : string;
55 | first_post_id : string;
56 | first_poster_name : string;
57 | last_post_id : string;
58 | last_poster_id : string;
59 | last_poster_name : string;
60 | last_post_subject : string;
61 | last_post_time : string;
62 | last_view_time : string;
63 | end;
64 |
65 |
66 | PstInfType = record // posts record
67 | id : string;
68 | topic_id : string;
69 | forum_id : string;
70 | user_id : string;
71 | poster_ip : string;
72 | post_time : string;
73 | post_subject : string;
74 | post_text: string;
75 | post_postcount: string;
76 | post_alpha : string;
77 | post_size : string;
78 | post_edit_time : string;
79 | post_edit_reason: string;
80 | post_edit_user : string;
81 | post_edit_count : string;
82 | post_edit_locked : string;
83 | end;
84 |
85 | usrInfType = record // user record
86 | iduser : string;
87 | Name : string;
88 | pwd : string;
89 | LastTime : string;
90 | TotalTime : string;
91 | MailAdress : string;
92 | CreateIP : string;
93 | CreateTime : string;
94 | RegisterIP : string;
95 | RegisterTime : string;
96 | isChecked : string;
97 | isVisible : string;
98 | picture_png : string;
99 | end;
100 |
101 |
102 | jobType = record // job server record
103 | idjobs : string ;
104 | inquirer : string ;
105 | inqIP : string ;
106 | inqTime : string ;
107 | idUser : string ;
108 | Action : string ;
109 | Intervall : string ;
110 | Result : string ;
111 | Status : string ;
112 | StatusMsg : string ;
113 | context : String;
114 | end;
115 |
116 |
117 | procedure cpyForumInfo( CONST qry:TSQLQuery; VAR memFrm:ForInfType );
118 | procedure cpyTopicInfo( CONST qry:TSQLQuery; VAR memFrm:TopInfType );
119 | procedure cpyPostInfo ( CONST qry:TSQLQuery; VAR PstFrm:PstInfType );
120 | procedure cpyUsrInfo ( CONST qry:TSQLQuery; VAR usrFrm:usrInfType );
121 | procedure cpySessInfo ( CONST qry:TSQLQuery; VAR SessFrm:sessInfType );
122 | procedure cpyJobInfo ( CONST qry:TSQLQuery; VAR myJob:jobType );
123 |
124 | function job_insert ( CONST conn: TMySQL55Connection; CONST myJob:JobType ): String;
125 |
126 | procedure ReadUsr ( CONST conn: TMySQL55Connection; CONST sUsr:string; VAR usrFrm:usrInfType );
127 | function User_insert ( CONST conn: TMySQL55Connection; CONST usrFrm:usrInfType ): String;
128 | function updUser ( CONST conn: TMySQL55Connection; CONST usrFrm:usrInfType ): String;
129 | function count_usr_themes( CONST conn: TMySQL55Connection; CONST usrRec: usrInfType ): String;
130 | function count_usr_posts( CONST conn: TMySQL55Connection; CONST usrRec: usrInfType ): String;
131 |
132 | Function Upd_Forum ( CONST conn: TMySQL55Connection; CONST memFrm:ForInfType ): STRING ;
133 | procedure ReadForum ( CONST conn: TMySQL55Connection; CONST idFrm:string; VAR usrFrm:ForInfType );
134 |
135 | procedure sesn_Read ( CONST conn: TMySQL55Connection; VAR sesnRec: sessInfType );
136 | function sesn_count ( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
137 | function sesn_close ( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
138 | function sesn_insert ( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
139 | function sesn_update ( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
140 |
141 | procedure Topic_Read ( CONST conn: TMySQL55Connection; VAR memFrm: TopInfType );
142 | Function Topic_Update( CONST conn: TMySQL55Connection; CONST memTpc: TopInfType ): STRING ;
143 | function topic_insert( CONST conn: TMySQL55Connection; CONST memFrm:TopInfType ): String;
144 |
145 | Function posts_Update( CONST conn: TMySQL55Connection; CONST memFrm: PstInfType ): STRING ;
146 | function posts_insert( CONST conn: TMySQL55Connection; CONST memFrm: PstInfType ): String;
147 | Function posts_Delete( CONST conn: TMySQL55Connection; CONST id:String ): STRING ;
148 | procedure posts_read ( CONST conn: TMySQL55Connection; VAR memFrm:PstInfType );
149 | Function posts_Count ( CONST conn: TMySQL55Connection; CONST dStart: String ): STRING ;
150 |
151 | Function GetContent (CONST conn: TMySQL55Connection; CONST sSearch:String ): STRING ;
152 | Function GetSetting (CONST conn : TMySQL55Connection; CONST inStrg: string): string;
153 |
154 | implementation
155 |
156 |
157 | Function GetSetting(CONST conn : TMySQL55Connection; CONST inStrg: string): string;
158 | VAR
159 | query : TSQLQuery;
160 |
161 | begin
162 |
163 | // query
164 | query := TSQLQuery.Create(nil);
165 | query.DataBase := conn;
166 | query.SQL.Text := 'select * from dbpara where qName="' + TRIM( inStrg ) + '"';
167 | query.Open;
168 |
169 | if query.EOF then
170 | begin
171 | query.active := false;
172 | query.free;
173 | exit;
174 | end;
175 |
176 | if query.Fields[5].AsInteger <> 0 then
177 | GetSetting := decrypt( query.Fields[4].AsString )
178 | else
179 | GetSetting := query.Fields[4].AsString;
180 |
181 | query.active := false;
182 | query.free;
183 |
184 | end;
185 |
186 | //////////////////////////////////////////////////////////
187 | // sample calls : GetContent(conn, 'bad_de' ): string;
188 | // GetContent(conn, 'bad_en' ): string;
189 |
190 | Function GetContent( CONST conn: TMySQL55Connection; CONST sSearch:String ): STRING ;
191 | VAR
192 | query : TSQLQuery;
193 |
194 | begin
195 | GetContent := 'none';
196 | // query
197 | query := TSQLQuery.Create(nil);
198 | query.DataBase := conn;
199 | query.SQL.Text := 'select * from contval where cName="' + TRIM( sSearch ) + '"';
200 | query.Open;
201 |
202 | if query.EOF then
203 | begin
204 | query.active := false;
205 | query.Free;
206 | exit;
207 | end;
208 |
209 | if query.Fields[5].AsInteger <> 0 then
210 | GetContent := decrypt( query.FieldByName('cValue').AsString )
211 | else
212 | GetContent := query.FieldByName('cValue').AsString ;
213 |
214 | query.active := false;
215 | query.Free;
216 |
217 | end;
218 |
219 | procedure cpyJobInfo ( CONST qry:TSQLQuery; VAR myJob:jobType );
220 | begin
221 | myJob.idjobs := qry.FieldByName('idjobs').AsString;
222 | myJob.inquirer := qry.FieldByName('inquirer').AsString;
223 | myJob.inqIP := qry.FieldByName('inqIP').AsString;
224 | myJob.inqTime := qry.FieldByName('inqTime').AsString;
225 | myJob.idUser := qry.FieldByName('idUser').AsString;
226 | myJob.Action := qry.FieldByName('Action').AsString;
227 | myJob.Intervall := qry.FieldByName('Intervall').AsString;
228 | myJob.Result := qry.FieldByName('Result').AsString;
229 | myJob.Status := qry.FieldByName('Status').AsString;
230 | myJob.StatusMsg := qry.FieldByName('StatusMsg').AsString;
231 | myJob.context := qry.FieldByName('context').AsString;
232 | end;
233 |
234 | procedure cpyUsrInfo ( CONST qry:TSQLQuery; VAR usrFrm:usrInfType );
235 | begin
236 | usrFrm.iduser := qry.FieldByName('iduser').AsString;
237 | usrFrm.Name := qry.FieldByName('Name').AsString;
238 | usrFrm.pwd := decrypt( qry.FieldByName('pwd').AsString );
239 | usrFrm.LastTime := qry.FieldByName('LastTime').AsString;
240 | usrFrm.TotalTime := qry.FieldByName('TotalTime').AsString;
241 | usrFrm.MailAdress := qry.FieldByName('MailAdress').AsString;
242 | usrFrm.CreateIP := qry.FieldByName('CreateIP').AsString;
243 | usrFrm.CreateTime := qry.FieldByName('CreateTime').AsString;
244 | usrFrm.RegisterIP := qry.FieldByName('RegisterIP').AsString;
245 | usrFrm.RegisterTime := qry.FieldByName('RegisterTime').AsString;
246 | usrFrm.isChecked := qry.FieldByName('isChecked').AsString;
247 | usrFrm.isVisible := qry.FieldByName('isVisible').AsString;
248 | usrFrm.picture_png := qry.FieldByName('picture_png').AsString;
249 |
250 | end;
251 |
252 | procedure cpyPostInfo( CONST qry:TSQLQuery; VAR PstFrm:PstInfType );
253 | begin
254 | PstFrm.id := qry.FieldByName('id').AsString;
255 | PstFrm.topic_id := qry.FieldByName('topic_id').AsString;
256 | PstFrm.forum_id := qry.FieldByName('forum_id').AsString;
257 | PstFrm.user_id := qry.FieldByName('user_id').AsString;
258 | PstFrm.poster_ip := qry.FieldByName('poster_ip').AsString;
259 | PstFrm.post_time := qry.FieldByName('post_time').AsString;
260 | PstFrm.post_subject := qry.FieldByName('post_subject').AsString;
261 | PstFrm.post_text := qry.FieldByName('post_text').AsString;
262 | PstFrm.post_postcount := qry.FieldByName('post_postcount').AsString;
263 | PstFrm.post_alpha := qry.FieldByName('post_alpha').AsString;
264 | PstFrm.post_size := qry.FieldByName('post_size').AsString;
265 | PstFrm.post_edit_time := qry.FieldByName('post_edit_time').AsString;
266 | PstFrm.post_edit_reason := qry.FieldByName('post_edit_reason').AsString;
267 | PstFrm.post_edit_user := qry.FieldByName('post_edit_user').AsString;
268 | PstFrm.post_edit_count := qry.FieldByName('post_edit_count').AsString;
269 | PstFrm.post_edit_locked := qry.FieldByName('post_edit_locked').AsString;
270 | end;
271 |
272 |
273 | procedure cpyTopicInfo( CONST qry:TSQLQuery; VAR memFrm:TopInfType );
274 | begin
275 | memFrm.id := qry.FieldByName('id').AsString;
276 | memFrm.forum_id := qry.FieldByName('forum_id').AsString;
277 | memFrm.title := qry.FieldByName('title').AsString;
278 | memFrm.topic_text := qry.FieldByName('topic_text').AsString;
279 | memFrm.poster := qry.FieldByName('poster').AsString;
280 | memFrm.poster_name := qry.FieldByName('poster_name').AsString;
281 | memFrm.ctime := qry.FieldByName('ctime').AsString;
282 | memFrm.time_limit := qry.FieldByName('time_limit').AsString;
283 | memFrm.views := qry.FieldByName('views').AsString;
284 | memFrm.replies := qry.FieldByName('replies').AsString;
285 | memFrm.replies_real := qry.FieldByName('replies_real').AsString;
286 | memFrm.first_post_id := qry.FieldByName('first_post_id').AsString;
287 | memFrm.first_poster_name := qry.FieldByName('first_poster_name').AsString;
288 | memFrm.last_post_id := qry.FieldByName('last_post_id').AsString;
289 | memFrm.last_poster_id := qry.FieldByName('last_poster_id').AsString;
290 | memFrm.last_poster_name := qry.FieldByName('last_poster_name').AsString;
291 | memFrm.last_post_subject := qry.FieldByName('last_post_subject').AsString;
292 | memFrm.last_post_time := qry.FieldByName('last_post_time').AsString;
293 | memFrm.last_view_time := qry.FieldByName('last_view_time').AsString;
294 | end;
295 |
296 |
297 | procedure cpyForumInfo( CONST qry:TSQLQuery; VAR memFrm:ForInfType );
298 | begin
299 | memFrm.id := qry.FieldByName('id').AsString;
300 | memFrm.fName := qry.FieldByName('fname').AsString;
301 | memFrm.fDesc := qry.FieldByName('fdesc').AsString;
302 | memFrm.fdesc_bitfield := qry.FieldByName('fdesc_bitfield').AsString;
303 | memFrm.fdesc_uid := qry.FieldByName('fdesc_uid').AsString;
304 | memFrm.topics_per_page := qry.FieldByName('topics_per_page').AsString;
305 | memFrm.posts := qry.FieldByName('posts').AsString;
306 | memFrm.topics := qry.FieldByName('topics').AsString;
307 | memFrm.topics_real := qry.FieldByName('topics_real').AsString;
308 | memFrm.last_post_id := qry.FieldByName('last_post_id').AsString;
309 | memFrm.last_poster_id := qry.FieldByName('last_poster_id').AsString;
310 | memFrm.last_post_subject := qry.FieldByName('last_post_subject').AsString;
311 | memFrm.last_post_time := qry.FieldByName('last_post_time').AsString;
312 | memFrm.last_poster_name := qry.FieldByName('last_poster_name').AsString;
313 | end;
314 |
315 |
316 | procedure cpySessInfo ( CONST qry:TSQLQuery; VAR SessFrm:sessInfType );
317 | begin
318 | SessFrm.rid := qry.FieldByName('rid').AsString;
319 | SessFrm.id := qry.FieldByName('id').AsString;
320 | SessFrm.user_id := qry.FieldByName('user_id').AsString;
321 | SessFrm.forum_id := qry.FieldByName('forum_id').AsString;
322 | SessFrm.is_active := qry.FieldByName('is_active').AsString;
323 | SessFrm.last_forum := qry.FieldByName('last_forum').AsString;
324 | SessFrm.browser := qry.FieldByName('browser').AsString;
325 | SessFrm.sip := qry.FieldByName('sip').AsString;
326 | SessFrm.sLat := qry.FieldByName('sLat').AsString;
327 | SessFrm.sLong := qry.FieldByName('sLong').AsString;
328 | SessFrm.latitude := qry.FieldByName('latitude').AsString;
329 | SessFrm.longitude := qry.FieldByName('longitude').AsString;
330 | SessFrm.accuracy := qry.FieldByName('accuracy').AsString;
331 | SessFrm.forwarded_for := qry.FieldByName('forwarded_for').AsString;
332 | SessFrm.v_order := qry.FieldByName('v_order').AsString;
333 | SessFrm.v_page := qry.FieldByName('v_page').AsString;
334 | SessFrm.v_rec := qry.FieldByName('v_rec').AsString;
335 | SessFrm.v_eof := qry.FieldByName('v_eof').AsString;
336 | SessFrm.viewonline := qry.FieldByName('viewonline').AsString;
337 | SessFrm.autologin := qry.FieldByName('autologin').AsString;
338 | SessFrm.admin := qry.FieldByName('admin').AsString;
339 | SessFrm.lastsearch := qry.FieldByName('lastsearch').AsString;
340 | SessFrm.lastlogin := qry.FieldByName('lastlogin').AsString;
341 | SessFrm.last_post_cnt := qry.FieldByName('last_post_cnt').AsString;
342 | SessFrm.login := qry.FieldByName('login').AsString;
343 | SessFrm.logout := qry.FieldByName('logout').AsString;
344 | end;
345 |
346 | procedure ReadForum(CONST conn:TMySQL55Connection; CONST idFrm:string; VAR usrFrm:ForInfType );
347 | VAR
348 | query2 : TSQLQuery;
349 |
350 | begin
351 | query2 := TSQLQuery.Create(nil);
352 | query2.DataBase := conn;
353 | query2.SQL.Text := 'select * from forums ' + idFrm ;
354 | query2.Open;
355 |
356 | if not query2.eof then cpyForumInfo( query2, usrFrm );
357 | query2.active := false;
358 | query2.Free;
359 |
360 |
361 | end;
362 |
363 | procedure ReadUsr(CONST conn:TMySQL55Connection; CONST sUsr:string; VAR usrFrm:usrInfType );
364 | VAR
365 | query2 : TSQLQuery;
366 |
367 | begin
368 | query2 := TSQLQuery.Create(nil);
369 | query2.DataBase := conn;
370 | query2.SQL.Text := 'select * from user ' + sUsr ;
371 | query2.Open;
372 |
373 | if not query2.eof then
374 | cpyUsrInfo( query2, usrFrm )
375 | else
376 | usrFrm.iduser:= '';
377 |
378 | query2.active := false;
379 | query2.Free;
380 |
381 |
382 | end;
383 |
384 | Function Upd_Forum( CONST conn: TMySQL55Connection; CONST memFrm: ForInfType ): STRING ;
385 | VAR
386 | query2 : TSQLQuery;
387 | sQry : STRING;
388 |
389 | begin
390 | sQry := 'UPDATE forums SET fname = "%%1", fdesc = "%%2", fdesc_bitfield = "%%3", fdesc_uid = %%4, topics_per_page = %%5, posts = %%6, '+
391 | 'topics = %%7, topics_real = %%8, last_post_id = %%9, last_poster_id = %%A, last_post_subject = "%%B", last_post_time = now(), last_poster_name = "%%C" ' +
392 | 'WHERE id = %%D;';
393 |
394 | sQry := sUpdate( sQry, '%%1', memFrm.fName );
395 | sQry := sUpdate( sQry, '%%2', memFrm.fDesc );
396 | sQry := sUpdate( sQry, '%%3', memFrm.fdesc_bitfield );
397 | sQry := sUpdate( sQry, '%%4', memFrm.fdesc_uid );
398 | sQry := sUpdate( sQry, '%%5', memFrm.topics_per_page );
399 | sQry := sUpdate( sQry, '%%6', memFrm.posts );
400 | sQry := sUpdate( sQry, '%%7', memFrm.topics );
401 | sQry := sUpdate( sQry, '%%8', memFrm.topics_real );
402 | sQry := sUpdate( sQry, '%%9', memFrm.last_post_id );
403 | sQry := sUpdate( sQry, '%%A', memFrm.last_poster_id );
404 | sQry := sUpdate( sQry, '%%B', memFrm.last_post_subject );
405 | sQry := sUpdate( sQry, '%%C', memFrm.last_poster_name );
406 | sQry := sUpdate( sQry, '%%D', memFrm.ID);
407 |
408 | query2 := TSQLQuery.Create(nil);
409 | query2.DataBase := conn;
410 | query2.SQL.Text := sQry;
411 | try
412 | query2.ExecSQL;
413 | conn.Transaction.Commit;
414 | except
415 | on e: Exception do Upd_Forum := e.Message + query2.SQL.Text;
416 | end;
417 |
418 | query2.active := False;
419 | query2.Free;
420 |
421 | end;
422 |
423 |
424 | function updUser( CONST conn: TMySQL55Connection; CONST usrFrm:usrInfType ): String;
425 | VAR
426 | query2 : TSQLQuery;
427 | sQry, d1, d2, d3 : STRING;
428 |
429 | begin
430 |
431 | // normalize datetime
432 | d1 := usrFrm.LastTime;
433 | d2 := usrFrm.CreateTime;
434 | d3 := usrFrm.RegisterTime;
435 | if d1 = '' then d1 := DateTimeToStr (now) ;
436 | if d2 = '' then d2 := d1;
437 | if d3 = '' then d3 := d1;
438 | d1 := FormatDateTime(sqlDate, StrToDateTime(d1));
439 | d2 := FormatDateTime(sqlDate, StrToDateTime(d2));
440 | d3 := FormatDateTime(sqlDate, StrToDateTime(d3));
441 |
442 | // build query
443 | sQry := 'UPDATE user SET Name = "%%1", pwd = "%%2", LastTime= "%%3", TotalTime=%%4, MailAdress="%%5", CreateIP="%%6", CreateTime="%%7", ' +
444 | 'RegisterIP="%%8", RegisterTime="%%9", isChecked="%%A", isVisible="%%B"';
445 | if usrFrm.picture_png <> '' then sQry += ', picture_png=x''%%C'' ';
446 | sQry += ' WHERE iduser= %%D';
447 |
448 |
449 | sQry := sUpdate( sQry, '%%1', usrFrm.Name );
450 | sQry := sUpdate( sQry, '%%2', encrypt(usrFrm.pwd) );
451 | sQry := sUpdate( sQry, '%%3', d1 );
452 | sQry := sUpdate( sQry, '%%4', usrFrm.TotalTime );
453 | sQry := sUpdate( sQry, '%%5', usrFrm.MailAdress );
454 | sQry := sUpdate( sQry, '%%6', usrFrm.CreateIP );
455 | sQry := sUpdate( sQry, '%%7', d2 );
456 | sQry := sUpdate( sQry, '%%8', usrFrm.RegisterIP );
457 | sQry := sUpdate( sQry, '%%9', d3 );
458 | sQry := sUpdate( sQry, '%%A', usrFrm.isChecked );
459 | sQry := sUpdate( sQry, '%%B', usrFrm.isVisible );
460 | if usrFrm.picture_png <> '' then
461 | sQry:=sUpdate(sQry, '%%C', usrFrm.picture_png );
462 | sQry := sUpdate( sQry, '%%D', usrFrm.iduser );
463 |
464 | // write to db
465 | query2 := TSQLQuery.Create(nil);
466 | query2.DataBase := conn;
467 | query2.SQL.Text := sQry;
468 | try
469 | query2.ExecSQL;
470 | conn.Transaction.Commit;
471 | except
472 | on e: Exception do updUser := e.Message + CHR(13) + sQry;
473 | end;
474 |
475 | query2.active := False;
476 | query2.Free;
477 |
478 | end;
479 |
480 |
481 |
482 | function posts_insert( CONST conn: TMySQL55Connection; CONST memFrm: PstInfType ): String;
483 | VAR
484 | i: integer;
485 | sTmp : string;
486 | query2 : TSQLQuery;
487 |
488 | begin
489 | posts_insert := '';
490 | query2 := TSQLQuery.Create(nil);
491 | query2.DataBase := conn;
492 | query2.SQL.Text := 'INSERT INTO posts ( topic_id, forum_id, user_id, poster_ip, post_subject, post_text, post_alpha, post_size )' +
493 | 'VALUES ( ' + memFrm.topic_id + ', ' + memFrm.forum_id + ', ' + memFrm.user_id + ', "' +
494 | memFrm.poster_ip + '", "' + memFrm.post_subject + '", x' + #39 + StrToHex(memfrm.post_text) + #39 + ', "' +
495 | memfrm.post_alpha + '", ' + memfrm.post_size +');';
496 | try
497 | query2.ExecSQL;
498 | conn.Transaction.Commit;
499 | except
500 | on e: Exception do posts_insert := 'posts_insert ' + e.Message + '--' + query2.SQL.Text;
501 | end;
502 |
503 | query2.active := False;
504 | query2.Free;
505 | end;
506 |
507 | function User_insert( CONST conn: TMySQL55Connection; CONST usrFrm:usrInfType ): String;
508 | VAR
509 | query2 : TSQLQuery;
510 |
511 | begin
512 | User_insert := '' ;
513 | query2 := TSQLQuery.Create(nil);
514 | query2.DataBase := conn;
515 | Query2.SQL.Text := 'INSERT INTO user (Name, pwd, LastTime, TotalTime, MailAdress, CreateIP, CreateTime ) VALUES ("' +
516 | usrFrm.Name + '", "' + usrFrm.pwd + '", now(), 0, "' + usrFrm.MailAdress + '", "' + usrFrm.RegisterIP + '", now() )';
517 | try
518 | query2.ExecSQL;
519 | conn.Transaction.Commit;
520 | except
521 | on e: Exception do User_insert := 'User_insert ' + e.Message;
522 | end;
523 |
524 | query2.active := False;
525 | query2.Free;
526 |
527 | end;
528 |
529 | function topic_insert( CONST conn: TMySQL55Connection; CONST memFrm: TopInfType ): String;
530 | VAR
531 | query2 : TSQLQuery;
532 |
533 | begin
534 | topic_insert := '';
535 | query2 := TSQLQuery.Create(nil);
536 | query2.DataBase := conn;
537 | query2.SQL.Text := 'INSERT INTO topics ( forum_id, title, topic_text, poster, poster_name, ctime ) ' +
538 | 'VALUES ( ' + memFrm.forum_id + ', "' + memFrm.title + '", x' + #39 + StrToHex(memFrm.topic_text) + #39 + ', ' +
539 | memFrm.poster + ', "' + memFrm.poster_name + '", now() );';
540 |
541 | try
542 | query2.ExecSQL;
543 | conn.Transaction.Commit;
544 | except
545 | on e: Exception do topic_insert := 'topic_insert ' + e.Message;
546 | end;
547 |
548 | query2.active := False;
549 | query2.Free;
550 |
551 | end;
552 |
553 |
554 | /////////////////////////////////////////////////
555 | // called on new session by sesn_insert
556 | // called on expired session by isSessionValid
557 |
558 | function sesn_close( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
559 | VAR
560 | query2 : TSQLQuery;
561 | sQry : STRING;
562 |
563 | begin
564 |
565 | sQry := 'UPDATE sessions ' +
566 | 'SET is_active="0", logout="' + FormatDateTime(sqlDate, now()) + '" ' +
567 | 'WHERE user_id="' + sesnRec.user_id + '";' ;
568 | query2 := TSQLQuery.Create(nil);
569 | query2.DataBase := conn;
570 | query2.SQL.Text := sQry;
571 | try
572 | query2.ExecSQL;
573 | conn.Transaction.Commit;
574 | except
575 | on e: Exception do sesn_close := 'sesn_close ' + e.Message;
576 | end;
577 |
578 | query2.active := False;
579 | query2.Free;
580 | end;
581 |
582 | function count_usr_posts( CONST conn: TMySQL55Connection; CONST usrRec: usrInfType ): String;
583 | VAR
584 | query2 : TSQLQuery;
585 | sQry : STRING;
586 |
587 | begin
588 | count_usr_posts := '0';
589 | query2 := TSQLQuery.Create(nil);
590 | query2.DataBase := conn;
591 | query2.SQL.Text := 'select count(*) from posts where user_id=' + usrRec.iduser ;
592 | query2.Open;
593 |
594 | if not query2.eof then count_usr_posts := query2.Fields[0].AsString;
595 | query2.active := False;
596 | query2.Free;
597 |
598 | end;
599 |
600 | function count_usr_themes( CONST conn: TMySQL55Connection; CONST usrRec: usrInfType ): String;
601 | VAR
602 | query2 : TSQLQuery;
603 | sQry : STRING;
604 |
605 | begin
606 | count_usr_themes := '0';
607 | query2 := TSQLQuery.Create(nil);
608 | query2.DataBase := conn;
609 | query2.SQL.Text := 'select count(*) from topics where poster=' + usrRec.iduser ;
610 | query2.Open;
611 |
612 | if not query2.eof then count_usr_themes := query2.Fields[0].AsString;
613 | query2.active := False;
614 | query2.Free;
615 |
616 | end;
617 |
618 |
619 | function sesn_count( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
620 | VAR
621 | query2 : TSQLQuery;
622 | sQry : STRING;
623 |
624 | begin
625 | sesn_count := '0';
626 | query2 := TSQLQuery.Create(nil);
627 | query2.DataBase := conn;
628 | query2.SQL.Text := 'select count(*) from sessions where is_active ="1";';
629 | query2.Open;
630 |
631 | if not query2.eof then sesn_count := query2.Fields[0].AsString;
632 | query2.active := False;
633 | query2.Free;
634 |
635 | end;
636 |
637 |
638 |
639 |
640 | function sesn_insert( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
641 | VAR
642 | query2 : TSQLQuery;
643 | s1,s2,s3,s4, s5 : String;
644 |
645 | begin
646 | // normalize paras - avoid blank
647 | s1 := iif( sesnRec.last_forum ='', '0', sesnRec.last_forum );
648 | s2 := iif( sesnRec.latitude ='', '0', sesnRec.latitude);
649 | s3 := iif( sesnRec.longitude ='', '0', sesnRec.longitude );
650 | s4 := iif( sesnRec.accuracy ='', '0', sesnRec.accuracy );
651 | s5 := iif( sesnRec.lastlogin ='',
652 | FormatDateTime(sqlDate, now()),
653 | FormatDateTime(sqlDate, StrToDateTime(sesnRec.lastlogin)));
654 |
655 | // close all open sessions for user_id
656 | sesn_close( conn, sesnRec );
657 |
658 | sesn_insert := '';
659 | query2 := TSQLQuery.Create(nil);
660 | query2.DataBase := conn;
661 | query2.SQL.Text := 'INSERT INTO sessions ( id, user_id, forum_id, is_active, last_forum, browser, sip, sLat, sLong, latitude, longitude, ' +
662 | 'accuracy, v_order, v_page, v_rec, v_eof, lastlogin, last_post_cnt ) ' +
663 | 'VALUES ( "' + sesnRec.id + '", ' + sesnRec.user_id + ' ,' + sesnRec.forum_id + ' ,"' + sesnRec.is_active + '", ' +
664 | s1 + ', "' + sesnRec.browser + '", "' + sesnRec.sip + '", ' + sesnRec.sLat + ', ' + sesnRec.sLong + ' ,' +
665 | s2 + ', ' + s3 + ', ' + s4 + ', ' + sesnRec.v_order + ', ' + sesnRec.v_page + ', ' + sesnRec.v_rec + ', ' +
666 | sesnRec.v_eof + ', "' + s5 + '", ' + sesnRec.last_post_cnt + ');';
667 | try
668 | query2.ExecSQL;
669 | conn.Transaction.Commit;
670 | except
671 | on e: Exception do sesn_insert := 'sesn_insert ' + e.Message;
672 | end;
673 |
674 | query2.active := False;
675 | query2.Free;
676 |
677 | end;
678 |
679 |
680 | function job_insert( CONST conn: TMySQL55Connection; CONST myJob:JobType ): String;
681 | VAR
682 | query2 : TSQLQuery;
683 |
684 | begin
685 | job_insert := '';
686 | query2 := TSQLQuery.Create(nil);
687 | query2.DataBase := conn;
688 | query2.SQL.Text := 'INSERT INTO jobs ( inquirer, inqIP, inqTime, idUser, Action, Intervall, context ) VALUES ("' +
689 | myJob.inquirer + '", "' + myJob.inqIP + '", now(), ' + myJob.iduser +', "' + myJob.Action +'", ' +
690 | myJob.Intervall + ', "' + myJob.context + '" )';
691 | try
692 | query2.ExecSQL;
693 | conn.Transaction.Commit;
694 | except
695 | on e: Exception do job_insert := 'job_insert ' + e.Message;
696 | end;
697 |
698 | query2.active := False;
699 | query2.Free;
700 |
701 | end;
702 |
703 |
704 | function sesn_update ( CONST conn: TMySQL55Connection; CONST sesnRec: sessInfType ): String;
705 | VAR
706 | query2 : TSQLQuery;
707 | sQry : STRING;
708 |
709 | begin
710 | sesn_update := '';
711 | sQry := 'UPDATE sessions SET is_active=%%1, forum_id=%%2, last_forum=%%3, forwarded_for="%%4", v_order=%%5, v_page=%%6, v_rec=%%7, v_eof=%%8, lastsearch="%%9" WHERE id="' + sesnRec.id + '";' ;
712 | sQry := sUpdate( sQry, '%%1', sesnRec.is_active );
713 | sQry := sUpdate( sQry, '%%2', sesnRec.forum_id );
714 | sQry := sUpdate( sQry, '%%3', sesnRec.last_forum );
715 | sQry := sUpdate( sQry, '%%4', sesnRec.forwarded_for );
716 | sQry := sUpdate( sQry, '%%5', sesnRec.v_order);
717 | sQry := sUpdate( sQry, '%%6', sesnRec.v_page );
718 | sQry := sUpdate( sQry, '%%7', sesnRec.v_rec );
719 | sQry := sUpdate( sQry, '%%8', sesnRec.v_eof );
720 | sQry := sUpdate( sQry, '%%9', sesnRec.lastsearch );
721 | query2 := TSQLQuery.Create(nil);
722 | query2.DataBase := conn;
723 | query2.SQL.Text := sQry;
724 | try
725 | query2.ExecSQL;
726 | conn.Transaction.Commit;
727 | except
728 | on e: Exception do sesn_update := query2.SQL.Text + ' -- sesn_update --' + e.Message;
729 | end;
730 |
731 | query2.active := False;
732 | query2.Free;
733 |
734 | end;
735 |
736 |
737 | procedure sesn_Read(CONST conn:TMySQL55Connection; VAR sesnRec: sessInfType );
738 | VAR
739 | query2 : TSQLQuery;
740 |
741 | begin
742 | query2 := TSQLQuery.Create(nil);
743 | query2.DataBase := conn;
744 | query2.SQL.Text := 'SELECT * FROM sessions WHERE id="' + sesnRec.id + '";';
745 | query2.Open;
746 |
747 | if not query2.eof then cpySessInfo ( query2, sesnRec );
748 | query2.active := false;
749 | query2.Free;
750 |
751 | end;
752 |
753 | procedure posts_read( CONST conn: TMySQL55Connection; VAR memFrm:PstInfType );
754 | VAR
755 | query2 : TSQLQuery;
756 |
757 | begin
758 | query2 := TSQLQuery.Create(nil);
759 | query2.DataBase := conn;
760 | query2.SQL.Text := 'SELECT * FROM posts WHERE id="' + memFrm.id + '";';
761 | query2.Open;
762 |
763 | if not query2.eof then
764 | cpyPostInfo( Query2, memFrm )
765 | else
766 | memFrm.id := '';
767 |
768 | query2.active := false;
769 | query2.Free;
770 |
771 | end;
772 |
773 |
774 | Function posts_Delete( CONST conn: TMySQL55Connection; CONST id:String ): STRING ;
775 | VAR
776 | query2 : TSQLQuery;
777 |
778 | begin
779 | posts_Delete := '';
780 | query2 := TSQLQuery.Create(nil);
781 | query2.DataBase := conn;
782 | query2.SQL.Text := 'DELETE FROM posts WHERE id=' + id + ';';
783 | try
784 | query2.ExecSQL;
785 | conn.Transaction.Commit;
786 | except
787 | on e: Exception do posts_Delete := e.Message + query2.SQL.Text;
788 | end;
789 |
790 | query2.active := False;
791 | query2.Free;
792 |
793 | end;
794 |
795 |
796 | Function posts_Count( CONST conn: TMySQL55Connection; CONST dStart: String ): STRING ;
797 | VAR
798 | query2 : TSQLQuery;
799 |
800 | begin
801 | posts_Count := '0';
802 | query2 := TSQLQuery.Create(nil);
803 | query2.DataBase := conn;
804 | query2.SQL.Text := 'select count(*) from posts where post_time > "'+
805 | FormatDateTime(sqlDate, StrToDateTime(dStart)) + '";';
806 | query2.Open;
807 |
808 | if not query2.eof then posts_Count := query2.Fields[0].AsString;
809 | query2.active := False;
810 | query2.Free;
811 |
812 | end;
813 |
814 | procedure Topic_Read(CONST conn:TMySQL55Connection; VAR memFrm: TopInfType );
815 | VAR
816 | query2 : TSQLQuery;
817 |
818 | begin
819 |
820 | if memFrm.id = '' then exit;
821 | query2 := TSQLQuery.Create(nil);
822 | query2.DataBase := conn;
823 | query2.SQL.Text := 'SELECT * FROM topics where id=' + memFrm.id ;
824 | query2.Open;
825 |
826 | if not query2.eof then
827 | cpyTopicInfo( Query2, memFrm )
828 | else
829 | memFrm.id := '';
830 |
831 | query2.active := false;
832 | query2.Free;
833 |
834 | end;
835 |
836 |
837 | Function posts_Update( CONST conn: TMySQL55Connection; CONST memFrm: PstInfType ): STRING ;
838 | VAR
839 | query2 : TSQLQuery;
840 | d1, d2, sQry: STRING;
841 |
842 | begin
843 |
844 | posts_Update := '';
845 | // normalize datetime
846 | d1 := memFrm.post_time;
847 | d2 := memFrm.post_edit_time;
848 | if d1 = '' then d1 := DateTimeToStr (now) ;
849 | if d2 = '' then d2 := d1;
850 | d1 := FormatDateTime(sqlDate, StrToDateTime(d1));
851 | d2 := FormatDateTime(sqlDate, StrToDateTime(d2));
852 | // make query string post_text=''%%7'' changed to post_text=%%7
853 | sQry := 'UPDATE posts SET topic_id= %%1, forum_id=%%2, user_id=%%3, poster_ip="%%4", post_time="%%5", post_subject="%%6", post_text=%%7, ' +
854 | 'post_postcount= %%8, post_alpha="%%9", post_size=%%A, post_edit_time="%%B", post_edit_reason="", post_edit_user=%%D, post_edit_count=%%E, post_edit_locked="%%F" ' +
855 | 'WHERE id=%%G;';
856 |
857 | sQry := sUpdate( sQry, '%%1', memFrm.topic_id );
858 | sQry := sUpdate( sQry, '%%2', memFrm.forum_id );
859 | sQry := sUpdate( sQry, '%%3', memFrm.user_id );
860 | sQry := sUpdate( sQry, '%%4', memFrm.poster_ip );
861 | sQry := sUpdate( sQry, '%%5', d1 );
862 | sQry := sUpdate( sQry, '%%6', memFrm.post_subject );
863 | // sQry := sUpdate( sQry, '%%7', memFrm.post_text );
864 | sQry := sUpdate( sQry, '%%7', 'x' + #39 + StrToHex(memFrm.post_text) + #39 );
865 | sQry := sUpdate( sQry, '%%8', memFrm.post_postcount );
866 |
867 | sQry := sUpdate( sQry, '%%9', memFrm.post_alpha );
868 | sQry := sUpdate( sQry, '%%A', memFrm.post_size );
869 |
870 | sQry := sUpdate( sQry, '%%B', d2 );
871 | sQry := sUpdate( sQry, '%%C', memFrm.post_edit_reason );
872 | sQry := sUpdate( sQry, '%%D', memFrm.post_edit_user );
873 | sQry := sUpdate( sQry, '%%E', memFrm.post_edit_count );
874 | sQry := sUpdate( sQry, '%%F', memFrm.post_edit_locked);
875 | sQry := sUpdate( sQry, '%%G', memFrm.id );
876 |
877 | query2 := TSQLQuery.Create(nil);
878 | query2.DataBase := conn;
879 | query2.SQL.Text := sQry;
880 | try
881 | query2.ExecSQL;
882 | conn.Transaction.Commit;
883 | except
884 | on e: Exception do posts_Update := e.Message + query2.SQL.Text;
885 | end;
886 |
887 | query2.active := False;
888 | query2.Free;
889 |
890 | end;
891 |
892 | Function Topic_Update( CONST conn: TMySQL55Connection; CONST memTpc: TopInfType ): STRING ;
893 | VAR
894 | query2 : TSQLQuery;
895 | d1, d2, d3, d4, sQry : STRING;
896 |
897 | begin
898 |
899 | Topic_Update := '';
900 | // normalize datetime
901 | d1 := memTpc.cTime;
902 | d2 := memTpc.time_limit;
903 | d3 := memTpc.last_post_time;
904 | d4 := memTpc.last_view_time;
905 | if d1 = '' then d1 := DateTimeToStr (now) ;
906 | if d2 = '' then d2 := '30.12.2099 00:00:00';
907 | if d3 = '' then d3 := d1;
908 | if d4 = '' then d4 := d1;
909 | d1 := FormatDateTime(sqlDate, StrToDateTime(d1));
910 | d2 := FormatDateTime(sqlDate, StrToDateTime(d2));
911 | d3 := FormatDateTime(sqlDate, StrToDateTime(d3));
912 | d4 := FormatDateTime(sqlDate, StrToDateTime(d4));
913 |
914 | // make query string Test: topic_text=%%3 instead of topic_text="%%3",
915 | sQry := 'UPDATE topics SET forum_id= %%1, title="%%2", topic_text=%%3, poster=%%4, poster_name="%%5", ctime= "%%6", ' +
916 | 'time_limit="%%7", views=%%8, replies=%%9, replies_real=%%A, first_post_id=%%B, first_poster_name="%%C", last_post_id=%%D, ' +
917 | 'last_poster_id=%%E, last_poster_name="%%F", last_post_subject="%%G", last_post_time="%%H", last_view_time="%%I" ' +
918 | 'WHERE id = %%J' ;
919 |
920 | sQry := sUpdate( sQry, '%%1', memTpc.forum_id );
921 | sQry := sUpdate( sQry, '%%2', memTpc.title );
922 | // sQry := sUpdate( sQry, '%%3', memTpc.topic_text );
923 | sQry := sUpdate( sQry, '%%3', 'x' + #39 + StrToHex(memTpc.topic_text) + #39 );
924 | sQry := sUpdate( sQry, '%%4', memTpc.poster );
925 | sQry := sUpdate( sQry, '%%5', memTpc.poster_name );
926 | sQry := sUpdate( sQry, '%%6', d1 );
927 | sQry := sUpdate( sQry, '%%7', d2 );
928 | sQry := sUpdate( sQry, '%%8', memTpc.views );
929 | sQry := sUpdate( sQry, '%%9', memTpc.replies );
930 | sQry := sUpdate( sQry, '%%A', memTpc.replies_real );
931 | sQry := sUpdate( sQry, '%%B', memTpc.first_post_id );
932 | sQry := sUpdate( sQry, '%%C', memTpc.first_poster_name );
933 | sQry := sUpdate( sQry, '%%D', memTpc.last_post_id);
934 | sQry := sUpdate( sQry, '%%E', memTpc.last_poster_id );
935 | sQry := sUpdate( sQry, '%%F', memTpc.last_poster_name );
936 | sQry := sUpdate( sQry, '%%G', memTpc.last_post_subject );
937 | sQry := sUpdate( sQry, '%%H', d3 );
938 | sQry := sUpdate( sQry, '%%I', d4 );
939 | sQry := sUpdate( sQry, '%%J', memTpc.id );
940 |
941 | query2 := TSQLQuery.Create(nil);
942 | query2.DataBase := conn;
943 | query2.SQL.Text := sQry;
944 | try
945 | query2.ExecSQL;
946 | conn.Transaction.Commit;
947 | except
948 | on e: Exception do Topic_Update := e.Message + query2.SQL.Text;
949 | end;
950 |
951 | query2.active := False;
952 | query2.Free;
953 |
954 | end;
955 |
956 | end.
957 |
958 |
--------------------------------------------------------------------------------
/menu.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_cgi
3 | // author : Ralph Berger
4 | // file : menu.pas
5 | // erstellt : 28.02.14
6 | // modified : RB - 21.03.2014
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 | // tested : yes
9 |
10 | unit Menu;
11 |
12 | {$mode objfpc}{$H+}
13 |
14 | interface
15 |
16 | uses
17 | Classes, SysUtils, Variants, synacode, FmtBCD, mysql55conn, sqldb, blowcryp, mapping ;
18 |
19 | CONST
20 | PageItems = 5;
21 | cgiPath = '/fcgi-bin/bbs/';
22 | err_page= 'bbs_error.html';
23 | MenuS_1 = ' TeamBBS Forum ';
24 | MenuS_1i= ' TeamBBS Forum ';
25 | MenuS_2 = ' Abmelden ' +
26 | ' Meine Nachrichten ';
27 |
28 | FootStr = '';
442 |
443 | end;
444 |
445 | end.
446 |
--------------------------------------------------------------------------------
/myaccnt.pas:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////
2 | // file : myAccnt.pas
3 | // called as 'cgi1/myacc'
4 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
5 |
6 | unit myAccnt;
7 |
8 | {$mode objfpc}{$H+}
9 |
10 | interface
11 |
12 | uses
13 | BrookAction, BrookFCLFCGIBroker, BrookConsts, BrookUtils, HTTPDefs, Classes, SysUtils,
14 | Variants, FmtBCD, sqldb, blowcryp, mapping, menu;
15 |
16 | type
17 | TMyAccnt = class(TBrookAction)
18 | public
19 | procedure Get; override;
20 | procedure Post; override;
21 | end;
22 |
23 | implementation
24 |
25 | procedure TMyAccnt.Get;
26 | VAR
27 | sMenu, sRet : String;
28 | myPara : ParaType;
29 | usrFrm1: usrInfType ;
30 |
31 |
32 | begin
33 | // check session
34 | myPara.VSession := Params.Values['sesn'];
35 | mypara.sip:= TheRequest.RemoteAddress;
36 | if NOT isSessionValid( mypara ) then
37 | begin
38 | Render(err_page, [myPara.lastError]);
39 | exit;
40 | end;
41 |
42 |
43 | // render record
44 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + inttostr(myPara.userID), usrFrm1 );
45 | sRet := sUpdate( accntEdt, '%%1', usrFrm1.Name );
46 | sRet := sUpdate( sRet, '%%2', usrFrm1.MailAdress );
47 | sRet := sUpdate( sRet, '%%3', usrFrm1.pwd );
48 | sRet := sUpdate( sRet, '%%4', usrFrm1.pwd );
49 | sRet := sUpdate( sRet, '%%5', showUsrImage(usrFrm1) );
50 | if usrFrm1.isVisible = 'False' then
51 | sRet := sUpdate( sRet, '%%6', ' ' )
52 | else
53 | sRet := sUpdate( sRet, '%%6', 'checked ="true"' );
54 |
55 | sRet := sUpdate( sRet, '%%7', mypara.VSession );
56 |
57 | mypara.sCmd := '1';
58 | sMenu := make_Header( myPara ) ;
59 | // don't show navi buttons
60 | mypara.sCmd := '0';
61 | Render('bbs_myacc.html', [sMenu,
62 | sRet,
63 | make_Footer(BrookFCLFCGIBroker.conn,mypara) ]);
64 |
65 | end;
66 |
67 |
68 |
69 |
70 | procedure TMyAccnt.Post;
71 | VAR
72 | i : integer;
73 | vPWD2, vagb, sRet : String;
74 | myPara : ParaType;
75 | usrFrm : usrInfType ;
76 | usrFrm1: usrInfType ;
77 | Stream : TMemoryStream;
78 | VFormItem: TUploadedFile;
79 |
80 |
81 | Begin
82 | vagb := Fields.Values['agb'];
83 | vPWD2:= Fields.Values['password_confirm'];
84 |
85 | usrFrm.Name := Fields.Values['usr_name'];
86 | usrFrm.MailAdress := Fields.Values['email'];
87 | usrFrm.pwd := Fields.Values['password'];
88 | usrFrm.isVisible := Fields.Values['vsbl'];
89 | usrFrm.picture_png := Fields.Values['bild'];
90 | myPara.VSession := Fields.Values['sesn'];
91 |
92 | // check session
93 | mypara.sip:= TheRequest.RemoteAddress;
94 | if NOT isSessionValid( mypara ) then
95 | begin
96 | Render(err_page, [myPara.lastError]);
97 | exit;
98 | end;
99 | usrFrm.iduser := inttostr( myPara.userID );
100 |
101 | // no navi bars
102 | mypara.sCmd := '0';
103 | // preset entry fault text
104 | sRet := accntErr;
105 |
106 | // translate input
107 | if usrFrm.isVisible = 'on' then
108 | usrFrm.isVisible := 'True'
109 | else
110 | usrFrm.isVisible := 'False';
111 |
112 | // punish code injection
113 | usrFrm.Name := SecuredStr( usrFrm.Name );
114 | usrFrm.pwd := SecuredStr( usrFrm.pwd );
115 | usrFrm.MailAdress := SecuredStr( usrFrm.MailAdress );
116 | if (usrFrm.Name = '') or (usrFrm.pwd ='') or (usrFrm.MailAdress = '') then
117 | begin
118 | sRet := sUpdate (sRet, '%%1', 'SQL Zeichen nicht erlaubt.');
119 | sRet := sUpdate (sRet, '%%2', 'Aktion abgebrochen !');
120 | Render('bbs_myacc.html', [make_Header_Accnt(mypara), sRet, make_Footer( conn, mypara ) ]);
121 | exit;
122 | end;
123 |
124 | // validate input
125 | if length( usrFrm.pwd ) < 6 then
126 | begin
127 | sRet := sUpdate (sRet, '%%1', 'Ihr Passwort muss mindesten 6 Zeichen lang sein.');
128 | sRet := sUpdate (sRet, '%%2', 'Bitte korrigieren ..');
129 | Render('bbs_myacc.html', [make_Header_Accnt(mypara), sRet, make_Footer( conn, mypara ) ]);
130 | exit;
131 | end;
132 |
133 | if usrFrm.pwd <> vPWD2 then
134 | begin
135 | sRet := sUpdate (sRet, '%%1', 'Passwort und Passwortbestätigung sind ungleich.');
136 | sRet := sUpdate (sRet, '%%2', 'Bitte korrigieren ..');
137 | Render('bbs_myacc.html', [make_Header_Accnt(mypara), sRet, make_Footer( conn, mypara ) ]);
138 | exit;
139 | end;
140 |
141 | // check input Image
142 | if usrFrm.picture_png <> '' then
143 | begin
144 | // check file type
145 | if UpperCase(RightStr(usrFrm.picture_png,3))<> 'PNG' then
146 | begin
147 | sRet := sUpdate (sRet, '%%1', 'Die Datei ' + usrFrm.picture_png + ' ist keine PNG Datei.');
148 | sRet := sUpdate (sRet, '%%2', 'Bitte ändern.');
149 | Render('bbs_myacc.html', [make_Header_Accnt(mypara), sRet, make_Footer( conn, mypara ) ]);
150 | exit;
151 | end;
152 |
153 | VFormItem := Files[0];
154 | // wait until file exists
155 | while not fileexists( BrookSettings.DirectoryForUploads +
156 | '\' + usrFrm.picture_png) do begin
157 | sleep(1000);
158 | // todo : add timeout
159 | end;
160 | // copy image from filesystem to string
161 | Stream := TMemoryStream.Create;
162 | stream.LoadFromFile( BrookSettings.DirectoryForUploads +
163 | '\' + usrFrm.picture_png );
164 | stream.position := 0;
165 | // limit png size to db field type mediumtext max
166 | if stream.size > 124000 then
167 | begin
168 | stream.free;
169 | sRet := sUpdate (sRet, '%%1', 'Die Datei ' + usrFrm.picture_png + ' ist zu groß. Maximum sind 124 kBytes.');
170 | sRet := sUpdate (sRet, '%%2', 'Bitte ändern.');
171 | Render('bbs_myacc.html', [make_Header_Accnt(mypara), sRet, make_Footer( conn, mypara ) ]);
172 | exit;
173 | end;
174 | // set picture_png to hexStr Format
175 | usrFrm.picture_png := '';
176 | for i:= 1 to stream.size do
177 | usrFrm.picture_png += IntToHex(stream.ReadByte,2);
178 | stream.free;
179 | end;
180 |
181 | // read user
182 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + usrFrm.iduser, usrFrm1 );
183 | usrFrm1.Name := usrFrm.Name ;
184 | usrFrm1.MailAdress := usrFrm.MailAdress;
185 | usrFrm1.pwd := usrFrm.pwd ;
186 | usrFrm1.isVisible := usrFrm.isVisible;
187 | usrFrm1.picture_png := usrFrm.picture_png;
188 |
189 | // sql update
190 | myPara.lastError := updUser( BrookFCLFCGIBroker.conn, usrFrm1 );
191 | if myPara.lastError <> '' then
192 | begin
193 | Render(err_page, [myPara.lastError]);
194 | exit;
195 | end;
196 |
197 | redirect ('./myacc?sesn=' + myPara.VSession, 302);
198 |
199 | end;
200 |
201 |
202 | initialization
203 | TMyAccnt.Register('myacc');
204 |
205 | end.
206 |
207 |
--------------------------------------------------------------------------------
/newpost.pas:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////
2 | // file : newpost.pas
3 | // created : 01.03.14
4 | // called via: 'cgi1/newpst?sesn=xxx&ID=1&Tpc=1'
5 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
6 | unit newPost;
7 |
8 | {$mode objfpc}{$H+}
9 |
10 | interface
11 |
12 | uses
13 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
14 | FmtBCD, sqldb, DateUtils, mapping, blowcryp, menu;
15 |
16 | type
17 | TNewPost = class(TBrookAction)
18 | public
19 | procedure Get; override;
20 | procedure Post; override;
21 | end;
22 |
23 | implementation
24 |
25 |
26 | procedure TNewPost.Get;
27 | VAR
28 | sBody, sFooter, sMenu, sTopic, sInfo : string;
29 | memFrm : ForInfType ;
30 | memTpc : TopInfType ;
31 | PstFrm : PstInfType ;
32 | usrFrm1: usrInfType ;
33 | usrFrm2: usrInfType ;
34 | myPara : ParaType;
35 |
36 | begin
37 |
38 | // check paras
39 | myPara.VSession := Params.Values['sesn'];
40 | memTpc.forum_id := Params.Values['Tpc'];
41 | memTpc.id := Params.Values['ID'];
42 | sMenu := Params.Values['B1'];
43 | sMenu += Params.Values['B2']; // form submits B1 or B2
44 | if memTpc.forum_id = '' then
45 | begin
46 | Render(err_page, ['Forum ID fehlt.']);
47 | exit;
48 | end;
49 |
50 | if memTpc.id = '' then
51 | begin
52 | Render(err_page, ['Topic ID fehlt.']);
53 | exit;
54 | end;
55 | mypara.sip:= TheRequest.RemoteAddress;
56 | if NOT isSessionValid( mypara ) then
57 | begin
58 | Render(err_page, [myPara.lastError]);
59 | exit;
60 | end;
61 |
62 | PstFrm.user_id := inttostr( myPara.userID );
63 | PstFrm.post_time:= FormatDateTime('yyyy-mm-dd hh:nn:ss', now) ;
64 |
65 | // read forum info
66 | ReadForum( BrookFCLFCGIBroker.conn, 'where id=' + memTpc.forum_id, memFrm );
67 | // read topic info
68 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
69 | // read user infos
70 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + PstFrm.user_id, usrFrm1 );
71 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + memTpc.poster, usrFrm2 );
72 | // set menu
73 | sFooter:= 'ha';
74 | sMenu := ' TeamBBS Forum ' +
75 | ' Forum: %%3 ' +
76 | ' Thema: %%4 ' +
77 | ' Abmelden ';
78 | sMenu := sUpdate ( sMenu, '%%0', myPara.VSession );
79 | sMenu := sUpdate ( sMenu, '%%1', memTpc.forum_id );
80 | sMenu := sUpdate ( sMenu, '%%2', memTpc.id );
81 | sMenu := sUpdate ( sMenu, '%%3', memFrm.fName );
82 | sMenu := sUpdate ( sMenu, '%%4', memTpc.title );
83 |
84 | // render topic
85 | sBody := '' ;
86 | sTopic := '
' +
87 | '' +
88 | ' %%7 ' +
89 | 'Erstellt von: %%2 am: %%3 - Letzter Aufruf von: %%4 am: %%5 ' +
90 | '' +
91 | '' +
92 | ' ' +
93 | '
' ;
94 |
95 | sTopic := sUpdate( sTopic, '%%1', showUsrImage(usrFrm2) );
96 | sTopic := sUpdate( sTopic, '%%2', memTpc.poster_name );
97 | sTopic := sUpdate( sTopic, '%%3', memTpc.ctime );
98 | sTopic := sUpdate( sTopic, '%%4', memTpc.last_poster_name );
99 | sTopic := sUpdate( sTopic, '%%5', memTpc.last_post_time );
100 | sTopic := sUpdate( sTopic, '%%6', memTpc.topic_text );
101 | sTopic := sUpdate( sTopic, '%%7', showUsrInfo(usrFrm2) );
102 |
103 | sBody += sTopic +
104 | '
' +
105 | '';
106 | sTopic := '
' ;
121 |
122 |
123 | sTopic := sUpdate( sTopic, '%%1', usrFrm1.Name );
124 | sTopic := sUpdate( sTopic, '%%2', PstFrm.post_time );
125 | sTopic := sUpdate( sTopic, '%%6', showUsrImage(usrFrm1) );
126 | sTopic := sUpdate( sTopic, '%%7', memTpc.id );
127 | sTopic := sUpdate( sTopic, '%%8', myPara.VSession );
128 | sTopic := sUpdate( sTopic, '%%9', memTpc.forum_id );
129 | sTopic := sUpdate( sTopic, '%%A', showUsrInfo(usrFrm1) );
130 | sBody += sTopic + '
';
131 | sBody += '
';
132 |
133 |
134 | // display topic & posts
135 | Render('bbs_thread.html', [sMenu, sBody, sFooter] );
136 |
137 | end;
138 |
139 |
140 | procedure TNewPost.Post;
141 | VAR
142 | I : Integer;
143 | sTmp : string;
144 | myPara : paraType;
145 | memFrm : ForInfType ;
146 | memTpc : TopInfType ;
147 | PstFrm : PstInfType ;
148 | usrFrm1: usrInfType ;
149 | badLst1: TStringList;
150 | badLst2: TStringList;
151 | myJob : JobType;
152 |
153 | begin
154 |
155 | mypara.sip := TheRequest.RemoteAddress;
156 | myPara.VSession := Fields.Values['sesn'];
157 | memTpc.id := Fields.Values['ID'];
158 | memTpc.forum_id := Fields.Values['Tpc'];
159 | PstFrm.post_text := Fields.Values['S2'];
160 | if NOT isSessionValid( mypara ) then
161 | begin
162 | Render(err_page, [myPara.lastError]);
163 | exit;
164 | end;
165 |
166 | PstFrm.user_id := IntToStr ( myPara.userID );
167 | PstFrm.poster_ip := mypara.sip;
168 |
169 |
170 | // read forum, topic, user
171 | ReadForum ( BrookFCLFCGIBroker.conn, 'where id=' + memTpc.forum_id, memFrm );
172 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
173 | ReadUsr ( BrookFCLFCGIBroker.conn, 'where iduser=' + PstFrm.user_id, usrFrm1 );
174 |
175 | // cut off bad words
176 | /// german
177 | sTmp := GetContent( BrookFCLFCGIBroker.conn, 'bad_de' );
178 | if sTmp <> 'none' then
179 | begin
180 | badLst1 := TStringList.Create;
181 | badLst1.TextLineBreakStyle := tlbsCRLF;
182 | badLst1.Text := sTmp;
183 | for I:=0 to badLst1.Count-1 do
184 | begin
185 | PstFrm.post_text:= StringReplace(PstFrm.post_text, TRIM(badLst1[i]),
186 | '/ups/', [rfReplaceAll, rfIgnoreCase]) ;
187 | end;
188 | badLst1.Free;
189 | end;
190 |
191 |
192 | /// english
193 | sTmp := GetContent( BrookFCLFCGIBroker.conn, 'bad_en' );
194 | if sTmp <> 'none' then
195 | begin
196 | badLst2 := TStringList.Create;
197 | badLst2.TextLineBreakStyle := tlbsCRLF;
198 | badLst2.Text := sTmp;
199 | for I:=0 to badLst2.Count-1 do
200 | begin
201 | PstFrm.post_text:= StringReplace(PstFrm.post_text, TRIM(badLst2[i]),
202 | '/ups/', [rfReplaceAll, rfIgnoreCase]) ;
203 | end;
204 | badLst2.Free;
205 | end;
206 |
207 |
208 | // append posts
209 | PstFrm.topic_id := memTpc.id ;
210 | PstFrm.forum_id := memTpc.forum_id;
211 | PstFrm.post_subject := memTpc.title;
212 | PstFrm.post_alpha := LeftStr( StripHTML( PstFrm.post_text) , 255 );
213 | PstFrm.post_size := IntToStr( Length ( PstFrm.post_text) );
214 | myPara.lastError := posts_insert( BrookFCLFCGIBroker.conn, PstFrm );
215 | if myPara.lastError <> '' then
216 | begin
217 | Render(err_page, [myPara.lastError]);
218 | exit;
219 | end;
220 |
221 | // update topic
222 | memTpc.views := sPlus( memTpc.views );
223 | memTpc.replies := sPlus( memTpc.replies );
224 | memTpc.replies_real := sPlus( memTpc.replies_real );
225 | memTpc.last_poster_id := PstFrm.user_id ;
226 | memTpc.last_poster_name := usrFrm1.Name;
227 | memTpc.last_post_subject:= PstFrm.Post_subject;
228 | memTpc.last_post_time := DateTimeToStr (now) ;
229 | memTpc.last_view_time := memTpc.last_post_time ;
230 |
231 | myPara.lastError := Topic_Update( BrookFCLFCGIBroker.conn, memTpc );
232 | if myPara.lastError <> '' then
233 | begin
234 | Render(err_page, [myPara.lastError]);
235 | exit;
236 | end;
237 |
238 | // update forum
239 | memFrm.topics := sPlus( memFrm.topics );
240 | memFrm.posts := sPlus( memFrm.posts );
241 | memFrm.last_poster_id := usrFrm1.iduser ;
242 | memFrm.last_poster_name := usrFrm1.Name;
243 | memFrm.last_post_subject := memTpc.title;
244 | myPara.lastError := Upd_Forum( BrookFCLFCGIBroker.conn, memFrm );
245 | if myPara.lastError <> '' then
246 | begin
247 | Render(err_page, [myPara.lastError]);
248 | exit;
249 | end;
250 |
251 | // start job info
252 | myJob.inquirer := conn.UserName;
253 | myJob.inqIP := PstFrm.poster_ip;
254 | myJob.Intervall := '0';
255 |
256 | // insert job 'badwords'
257 | if POS( '/ups/', PstFrm.post_text ) > 0 then
258 | begin
259 | myJob.iduser := PstFrm.user_id ;
260 | myJob.Action := 'badwords';
261 | myJob.Context := '|' + memTpc.id + '|' ;
262 | job_insert ( BrookFCLFCGIBroker.conn, myJob );
263 | end;
264 |
265 | // Insert job 'postinfo'
266 | myJob.iduser := memTpc.poster;
267 | myJob.Action := 'postinfo';
268 | myJob.Context := '|' + usrfrm1.iduser + '|' + memTpc.id + '|';
269 | job_insert ( BrookFCLFCGIBroker.conn, myJob );
270 |
271 |
272 | redirect ('topic?ID=' + PstFrm.forum_id + '&Tpc=' + PstFrm.topic_id + '&sesn=' + myPara.VSession , 302);
273 |
274 |
275 | end;
276 |
277 | initialization
278 | TNewPost.Register('newpst');
279 |
280 | end.
281 |
282 |
--------------------------------------------------------------------------------
/news.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 07.05.14
5 | // file : news.pas
6 | // list posts & topics sind last login
7 |
8 | unit news;
9 |
10 | {$mode objfpc}{$H+}
11 |
12 | interface
13 |
14 | uses
15 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
16 | FmtBCD, sqldb, blowcryp, mapping, menu;
17 |
18 | type
19 | Tnews = class(TBrookAction)
20 | public
21 | procedure Get; override;
22 | end;
23 |
24 | implementation
25 |
26 | procedure Tnews.Get;
27 | var
28 | i : integer;
29 | sRslt, body, sDate : String;
30 | mySessn: sessInfType;
31 | myPara : paraType;
32 | query : TSQLQuery;
33 |
34 | begin
35 |
36 | // read paras
37 | myPara.VSession := Params.Values['sesn'];
38 |
39 | // check session timeout
40 | mypara.sip:= TheRequest.RemoteAddress;
41 | if NOT isSessionValid( mypara ) then
42 | begin
43 | Render(err_page, ['session timeout ' + myPara.lastError + myPara.VSession + inttostr(i) ]);
44 | exit;
45 | end;
46 |
47 | // get session info
48 | paraTypeInit('news?', myPara ); // init mypara
49 | mypara.sCmd := '1'; // '1' full menus
50 | mySessn.id := mypara.VSession; // read session rec
51 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
52 | sesn_copy_para( mySessn, myPara );
53 |
54 |
55 | // build query
56 | sRslt := 'SELECT * from find where post_time > "' +
57 | FormatDateTime(sqlDate, StrToDateTime(mySessn.lastlogin)) + '" ';
58 |
59 | // set display order
60 | case myPara.v_order of
61 | '1' : sRslt += ' ORDER BY post_time';
62 | '2' : sRslt += ' ORDER BY iduser';
63 | '3' : sRslt += ' ORDER BY forum_id';
64 | end;
65 |
66 | // set limit ( start,stop )
67 | sRslt += ' limit ' +
68 | IntToStr( StrToInt( myPara.v_page ) * PageItems ) + ',' +
69 | IntToStr( StrToInt( myPara.v_page ) * PageItems + PageItems+1 );
70 |
71 | //////////////////////
72 | // main query
73 | query := TSQLQuery.Create(nil);
74 | query.DataBase := BrookFCLFCGIBroker.conn;
75 | query.SQL.Text := sRslt;
76 | query.Open;
77 |
78 | i := 0;
79 | body := '';
80 | while not query.EOF do
81 | begin
82 | sRslt := sUpdate(findrslt,'%%1','' +
84 | query.FieldByName('fname').AsString + ' ' );
85 | sRslt := sUpdate( sRslt, '%%2','' +
88 | query.FieldByName('title').AsString + ' ' );
89 | sRslt := sUpdate( sRslt, '%%3',StripHTML( query.FieldByName('post_text').AsString) );
90 | sRslt := sUpdate( sRslt, '%%4','' +
92 | query.FieldByName('Name').AsString + ' ' );
93 | body += sRslt;
94 | i += 1;
95 | if i = PageItems then break;
96 | query.next;
97 | end;
98 |
99 | // Build last table line
100 | sRslt := sUpdate( newsinfo, '%%5', mySessn.lastlogin);
101 | body += sRslt;
102 |
103 | // set footer info
104 | myPara.v_eof := iif( query.EOF, '1', '0'); // eof flag
105 |
106 | // show page
107 | Render('bbs_news.html', [ make_header(mypara), // header
108 | body, // body
109 | make_footer( BrookFCLFCGIBroker.conn, mypara) ]); // footer
110 | // release mem
111 | query.active := False;
112 | query.Free;
113 |
114 | end;
115 |
116 | initialization
117 | Tnews.Register('news');
118 |
119 | end.
120 |
121 |
--------------------------------------------------------------------------------
/newthm.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 11.02.14
5 | // file : newThm.pas
6 | // modified : 12.03.14
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 | // called via: 'cgi1/forum?ID=XXXX&sesn=XXXXXXXXXXXXXXX'
9 |
10 | unit newThm;
11 |
12 | {$mode objfpc}{$H+}
13 |
14 | interface
15 |
16 | uses
17 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
18 | FmtBCD, sqldb, blowcryp, mapping, menu;
19 |
20 | type
21 | TnewThm = class(TBrookAction)
22 | public
23 | procedure Get; override;
24 | procedure Post; override;
25 | end;
26 |
27 | implementation
28 |
29 | procedure TnewThm.Get;
30 | VAR
31 | memQry : ForInfType;
32 | memTpc : TopInfType;
33 | usrFrm1: usrInfType;
34 | myPara : ParaType;
35 |
36 | begin
37 |
38 | // check paras
39 | memTpc.forum_id := Params.Values['ID'];
40 | myPara.VSession := Params.Values['sesn'];
41 | mypara.sip:= TheRequest.RemoteAddress;
42 | if NOT isSessionValid( mypara ) then
43 | begin
44 | Render(err_page, [myPara.lastError]);
45 | exit;
46 | end;
47 |
48 | if memTpc.forum_id = '' then
49 | begin
50 | Render(err_page, ['Forum ID fehlt.']);
51 | exit;
52 | end;
53 |
54 | // copy from db to record
55 | ReadForum( BrookFCLFCGIBroker.conn, 'where id=' + memTpc.forum_id, memQry );
56 | ReadUsr ( BrookFCLFCGIBroker.conn, 'where iduser=' + IntToStr(myPara.userID), usrFrm1 );
57 |
58 | // start render
59 | myPara.Text1 := 'newthm?' ; // saved in session.forward_for
60 | myPara.sID := memTpc.forum_id ;
61 | myPara.sTopic:= memQry.fName ;
62 |
63 | Render('bbs_newthm.html', [ make_Header_newThm(mypara),
64 | showUsrImage(usrFrm1), // Usr Image
65 | showUsrInfo(usrFrm1), // Usr Info
66 | usrFrm1.Name, // Column 2 Usr Name
67 | memQry.fName, // Column 2 Forum Name
68 | mypara.VSession,
69 | memTpc.forum_id,
70 | make_Footer( BrookFCLFCGIBroker.conn, mypara ) ]);
71 |
72 |
73 | end;
74 |
75 |
76 | procedure TnewThm.Post;
77 | VAR
78 | memFrm : ForInfType;
79 | memTpc : TopInfType;
80 | usrFrm1: usrInfType;
81 | sNotify: string;
82 | myPara : ParaType;
83 |
84 | begin
85 |
86 | // read para
87 | sNotify := Fields.Values['vsbl'];
88 | myPara.VSession := Fields.Values['sesn'];
89 | mypara.sCmd := Fields.Values['B1'];
90 | mypara.sCmd += Fields.Values['B2']; // form posts B1 or B2
91 | memTpc.forum_id := Fields.Values['forum'];
92 | memTpc.title := Fields.Values['tpc_name'];
93 | memTpc.topic_text:= Fields.Values['S1'];
94 | // check session
95 | mypara.sip:= TheRequest.RemoteAddress;
96 | if NOT isSessionValid( mypara ) then
97 | begin
98 | Render(err_page, [myPara.lastError]);
99 | exit;
100 | end;
101 |
102 | // check submit button
103 | if mypara.sCmd <> 'Senden' then redirect ('./main?sesn=' + mypara.VSession, 302);
104 |
105 | usrFrm1.iduser := inttostr( mypara.userID );
106 | memTpc.poster := usrFrm1.iduser;
107 |
108 |
109 | ReadForum( BrookFCLFCGIBroker.conn, 'where id=' + memTpc.forum_id, memFrm );
110 | ReadUsr ( BrookFCLFCGIBroker.conn, 'where iduser=' + usrFrm1.iduser, usrFrm1 );
111 | memTpc.poster_name := usrFrm1.Name;
112 |
113 | // insert new topic
114 | myPara.lastError := topic_insert( BrookFCLFCGIBroker.conn, memTpc );
115 | if myPara.lastError <> '' then
116 | begin
117 | Render(err_page, [myPara.lastError]);
118 | exit;
119 | end;
120 |
121 | // update forum
122 | memFrm.topics := sPlus( memFrm.topics );
123 | memFrm.posts := sPlus( memFrm.posts );
124 | memFrm.last_poster_id := usrFrm1.iduser ;
125 | memFrm.last_poster_name := usrFrm1.Name;
126 | memFrm.last_post_subject:= memTpc.title;
127 | myPara.lastError := Upd_Forum( BrookFCLFCGIBroker.conn, memFrm );
128 | if myPara.lastError <> '' then
129 | begin
130 | Render(err_page, [myPara.lastError]);
131 | exit;
132 | end;
133 |
134 | redirect ('./forum?ID=' + memTpc.forum_id + '&sesn=' + myPara.VSession, 302);
135 |
136 | end;
137 |
138 | initialization
139 | TnewThm.Register('newthm');
140 |
141 | end.
142 |
143 |
--------------------------------------------------------------------------------
/posts.pas:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // file : posts.pas
4 | // created : 02.03.14
5 | // called via: 'cgi1/topic?ID=1;Tpc=1'
6 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
7 |
8 | unit posts;
9 | {$mode objfpc}{$H+}
10 |
11 | interface
12 |
13 | uses
14 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
15 | FmtBCD, sqldb, DateUtils, mapping, blowcryp, menu;
16 |
17 | type
18 | TPosts = class(TBrookAction)
19 | public
20 | procedure Get; override;
21 | end;
22 |
23 | implementation
24 |
25 |
26 |
27 | procedure TPosts.Get;
28 | var
29 | I : Integer;
30 | sMenu, sBody, sTopic, sTmp, sPage : string;
31 | memFrm : ForInfType;
32 | memTpc : TopInfType;
33 | PstFrm : PstInfType;
34 | usrFrm1: usrInfType;
35 | usrFrm2: usrInfType;
36 | mySessn: sessInfType;
37 | myPara : paraType;
38 | query : TSQLQuery;
39 |
40 | begin
41 |
42 | // check paras
43 | mypara.sip := TheRequest.RemoteAddress;
44 | myPara.VSession := Params.Values['sesn'];
45 | memTpc.forum_id := Params.Values['ID'];
46 | memTpc.id := Params.Values['Tpc'];
47 | sPage := Params.Values['page']; // resest vpage para
48 |
49 | if memTpc.forum_id = '' then
50 | begin
51 | Render(err_page, ['Forum ID fehlt: ' + memTpc.forum_id ]);
52 | exit;
53 | end;
54 |
55 | if memTpc.id = '' then
56 | begin
57 | Render(err_page, ['Topic ID fehlt: ' + memTpc.id ]);
58 | exit;
59 | end;
60 |
61 |
62 | if NOT isSessionValid( mypara ) then
63 | begin
64 | Render(err_page, [myPara.lastError]);
65 | exit;
66 | end;
67 |
68 | // read forum info
69 | ReadForum( BrookFCLFCGIBroker.conn, 'where id=' + memTpc.forum_id, memFrm );
70 | // read session user
71 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + inttostr(mypara.userID), usrFrm1 );
72 | // read topic info
73 | Topic_Read( BrookFCLFCGIBroker.conn, memTpc );
74 | // refresh topic access infos
75 | memTpc.views := sPlus( memTpc.Views );
76 | memTpc.last_view_time := DateTimeToStr( now());
77 | memTpc.last_poster_name := usrFrm1.Name;
78 | Topic_Update( BrookFCLFCGIBroker.conn, memTpc );
79 | // read topic user
80 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + memTpc.poster, usrFrm1 );
81 |
82 | // render topic
83 | sTopic := '' +
84 | '
' +
85 | '' +
86 | ' %%A ' +
87 | 'Erstellt von: %%2 am: %%3 - Letzter Aufruf von: %%4 am: %%5 ' +
88 | '' +
89 | '' +
90 | '' +
97 | ' ' +
98 | '';
104 |
105 | /// show topic edit button if current user = topic creator
106 | if inttostr( mypara.userID ) = memTpc.poster then
107 | sTopic += '' ;
113 |
114 | sTopic += '
';
115 | sTopic := sUpdate( sTopic, '%%1', showUsrImage(usrFrm1) );
116 | sTopic := sUpdate( sTopic, '%%2', memTpc.poster_name );
117 | sTopic := sUpdate( sTopic, '%%3', memTpc.ctime );
118 | sTopic := sUpdate( sTopic, '%%4', memTpc.last_poster_name );
119 | sTopic := sUpdate( sTopic, '%%5', memTpc.last_view_time );
120 | sTopic := sUpdate( sTopic, '%%6', memTpc.topic_text );
121 | sTopic := sUpdate( sTopic, '%%7', memTpc.id );
122 | sTopic := sUpdate( sTopic, '%%8', mypara.VSession );
123 | sTopic := sUpdate( sTopic, '%%9', memTpc.forum_id );
124 | sTopic := sUpdate( sTopic, '%%A', showUsrInfo(usrFrm1) );
125 | sBody := sTopic;
126 |
127 | // read sesion info to set display order
128 | mySessn.id := mypara.VSession;
129 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
130 | // reset page count if spage=0
131 | if spage = '0' then
132 | begin
133 | mySessn.v_page:='0';
134 | sesn_update( BrookFCLFCGIBroker.conn, mySessn );
135 | end;
136 |
137 | case mySessn.v_order of
138 | '0' : sTmp := '' ;
139 | '1' : sTmp := ' ORDER BY post_time';
140 | '2' : sTmp := ' ORDER BY post_size';
141 | '3' : sTmp := ' ORDER BY post_alpha';
142 | end;
143 |
144 |
145 | // set session info
146 | mypara.sCmd := '1'; // '1' full menus
147 | myPara.sID := memTpc.forum_id;
148 | myPara.sTopic := memFrm.fName ;
149 | myPara.sPst := memTpc.id;
150 | myPara.v_page := mySessn.v_page;
151 | myPara.Text1 := 'topic?ID=' + memTpc.forum_id + '&Tpc=' + memTpc.id; // saved in session.forward_for
152 | myPara.text2 := memTpc.title;
153 |
154 | // read posts info
155 | query := TSQLQuery.Create(nil);
156 | query.DataBase := BrookFCLFCGIBroker.conn;
157 | query.SQL.Text := 'SELECT * FROM posts where topic_id=' + memTpc.id +
158 | sTmp + // order by
159 | ' limit ' + // limit start,stop
160 | IntToStr( StrToInt( mySessn.v_page ) * PageItems )
161 | + ',' + IntToStr( StrToInt( mySessn.v_page ) * PageItems + PageItems+1 );
162 | query.Open;
163 | if query.EOF then
164 | begin
165 | // set menu info for topic w/o posts
166 | myPara.sID := memTpc.forum_id;
167 | myPara.sTopic := memFrm.fName ;
168 | myPara.sPst := memTpc.id;
169 | myPara.text2 := memTpc.title;
170 | sMenu := make_Header_Posts( myPara );
171 | mypara.sCmd := '0'; // switch off navi bars in footer
172 | Render('bbs_thread.html', [sMenu, sBody, make_Footer( BrookFCLFCGIBroker.conn, mypara )] );
173 | // free mem
174 | query.active := false;
175 | query.free;
176 | exit;
177 | end;
178 |
179 |
180 |
181 | // render posted replies
182 | i := 0;
183 | sBody := sBody + '';
184 | while not query.EOF do
185 | begin
186 | // read
187 | cpyPostInfo( Query, PstFrm );
188 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + PstFrm.user_id, usrFrm1 );
189 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + PstFrm.post_edit_user, usrFrm2 );
190 |
191 | // build display string
192 | sTopic := '
' +
193 | 'Antwort von: %%1 am: %%2 - Letzter Aufruf von: %%3 am: %%4 ' +
194 | ' %%A ' +
195 | ' ' +
196 | ' ';
197 |
198 | // show post edit buttons if current user = post creator
199 | if inttostr( mypara.userID ) = PstFrm.user_id then
200 | sTopic += '' ;
207 |
208 | sTopic += '
' ;
209 | sTopic := sUpdate( sTopic, '%%1', usrFrm1.Name );
210 | sTopic := sUpdate( sTopic, '%%2', PstFrm.post_time );
211 | sTopic := sUpdate( sTopic, '%%3', usrFrm2.Name );
212 | sTopic := sUpdate( sTopic, '%%4', PstFrm.post_edit_time );
213 | sTopic := sUpdate( sTopic, '%%5', PstFrm.post_text );
214 | sTopic := sUpdate( sTopic, '%%6', showUsrImage(usrFrm1) );
215 | sTopic := sUpdate( sTopic, '%%A', showUsrInfo(usrFrm1) );
216 |
217 | // set post edit buttons links
218 | if inttostr( mypara.userID ) = PstFrm.user_id then
219 | begin
220 | sTopic := sUpdate( sTopic, '%%7', PstFrm.id );
221 | sTopic := sUpdate( sTopic, '%%8', mypara.VSession );
222 | sTopic := sUpdate( sTopic, '%%9', PstFrm.user_id );
223 | end;
224 | sBody += sTopic + '
';
225 | i += 1;
226 | if i = PageItems then break;
227 | query.next;
228 | end;
229 | sBody += '
';
230 |
231 | mypara.V_rec := query.FieldByName('id').asString;
232 | if query.EOF then
233 | mypara.v_eof := '1'
234 | ELSE
235 | mypara.v_eof := '0';
236 |
237 |
238 | // set menu
239 | mypara.sCmd := '1'; // '1' full menus
240 | myPara.sID := memTpc.forum_id;
241 | myPara.sTopic := memFrm.fName ;
242 | myPara.sPst := memTpc.id;
243 | myPara.Text1 := 'topic?ID=' + memTpc.forum_id + '&Tpc=' + memTpc.id; // saved in session.forward_for
244 | myPara.text2 := memTpc.title;
245 |
246 | // display topic & posts
247 | Render('bbs_thread.html', [make_Header_Posts( myPara ),
248 | sBody,
249 | make_Footer( BrookFCLFCGIBroker.conn, mypara )] );
250 |
251 | // release mem
252 | query.active := false;
253 | query.free;
254 |
255 | end;
256 |
257 |
258 | initialization
259 | TPosts.Register('topic');
260 |
261 | end.
262 |
263 |
--------------------------------------------------------------------------------
/registerusr.pas:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////
2 | // file : RegisterUsr.pas
3 | // called as 'cgi1/account'
4 | // modified : 03.03.14
5 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
6 | // function
7 | // check fields, prompt on non unique vName
8 | // add entry to eaihot table for confirmation mail
9 | // eaihot records are processed by eaihot daemon.
10 | // new & approve account 'cgi1/approve'
11 |
12 | unit RegisterUsr;
13 |
14 | {$mode objfpc}{$H+}
15 |
16 | interface
17 |
18 | uses
19 | BrookAction, BrookFCLFCGIBroker, BrookConsts, SysUtils, Variants,
20 | FmtBCD, sqldb, mapping, blowcryp, menu;
21 |
22 |
23 | type
24 | TAccount = class(TBrookAction)
25 | public
26 | procedure Get; override;
27 | end;
28 |
29 | TApprove = class(TBrookAction)
30 | public
31 | procedure get; override;
32 | end;
33 |
34 | implementation
35 |
36 |
37 | /////////////////////////////////////////////////////////////////
38 | // Confirm Mail Handler:
39 | // .. confirm request by klicking link below:
40 | // http://localhost/cgi-bin/cgi1/approve?ID=38000026016823
41 | procedure TApprove.Get;
42 | var
43 | sID, sRet : String;
44 | myPara : ParaType;
45 | usrFrm : usrInfType;
46 |
47 |
48 | begin
49 | // parse parameters
50 | myPara.VSession := Params.Values['ID'];
51 | // no navi bars
52 | mypara.sCmd := '0';
53 | sRet := ' Hallo, die Aktivierung des Accounts muss innerhalb 24 Stunden ' +
54 | 'erfolgen. Eine spätere Aktivierung ist nicht möglich Bitte erstellen Sie einen neuen Account. ' +
55 | '
';
56 |
57 |
58 | // parse session string
59 | myPara.sIP := TheRequest.RemoteAddress;
60 | if decodeSessionID( myPara ) > 1440 then
61 | begin
62 | Render('bbs_accnt.html', [make_Header(mypara), sRet, make_Footer( conn, mypara )]);
63 | exit;
64 | end;
65 |
66 |
67 | // ReadUsr
68 | usrFrm.iduser := IntToStr(myPara.userID);
69 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + usrFrm.iduser, usrFrm );
70 | if usrFrm.iduser = '' then
71 | begin
72 | Render('bbs_accnt.html', [make_Header(mypara),
73 | sRet,
74 | make_Footer( BrookFCLFCGIBroker.conn, mypara )]);
75 | exit;
76 | end;
77 |
78 | // update vars
79 | usrFrm.RegisterIP := myPara.sIP;
80 | usrFrm.RegisterTime := DateTimeToStr( now ) ;
81 | usrFrm.isChecked := 'True';
82 | myPara.lastError := updUser(BrookFCLFCGIBroker.conn,usrFrm);
83 | if myPara.lastError <> '' then
84 | begin
85 | Render(err_page, [myPara.lastError]);
86 | exit;
87 | end;
88 |
89 | sRet := ' Hallo ' + usrFrm.Name + ', Ihr Account ist aktiviert. Ihre Mail Adresse: ' +
90 | usrFrm.MailAdress + '
';
91 |
92 | Render('bbs_accnt.html', [make_Header(mypara),
93 | sRet,
94 | make_Footer( BrookFCLFCGIBroker.conn, mypara )]);
95 |
96 | end;
97 |
98 | procedure TAccount.Get;
99 | var
100 | i: integer;
101 | vPWD2, vagb, sRet : string;
102 | myPara : ParaType;
103 | usrFrm : usrInfType;
104 | myJob : JobType;
105 |
106 | begin
107 |
108 | // no navi bars
109 | mypara.sCmd := '0';
110 |
111 |
112 | if Params.Count = 0 then
113 | begin
114 | sRet := 'Benutzername
' +
115 | ' ' +
116 | 'eMail
' +
117 | ' ' +
118 | 'Passwort
' +
119 | ' ' +
120 | 'Passwort bestätigen
' +
121 | ' ' +
122 | ' Ich stimme den Nutzungsbedingungen zu ' +
123 | '
';
124 | Render('bbs_accnt.html', [make_Header(mypara), sRet, make_Footer( conn, mypara )]);
125 | exit;
126 | end;
127 |
128 | // read paras
129 | vPWD2:= Params.Values['password_confirm'];
130 | vagb := Params.Values['agb'];
131 |
132 | mypara.VSession := Params.Values['sesn'];
133 | usrFrm.Name := Params.Values['usr_name'];
134 | usrFrm.MailAdress := Params.Values['emailsignup'];
135 | usrFrm.pwd := Params.Values['password'];
136 | // punish code injection
137 | usrFrm.Name := SecuredStr( usrFrm.Name );
138 | usrFrm.pwd := SecuredStr( usrFrm.pwd );
139 | usrFrm.MailAdress := SecuredStr( usrFrm.MailAdress );
140 |
141 | // preset entry fault text
142 | sRet := accntErr;
143 |
144 | // check paras
145 | if (usrFrm.Name = '') or (usrFrm.pwd ='') or (usrFrm.MailAdress = '') then
146 | begin
147 | sRet := sUpdate (sRet, '%%1', 'SQL Zeichen nicht erlaubt.');
148 | sRet := sUpdate (sRet, '%%2', 'Aktion abgebrochen !');
149 | Render('bbs_accnt.html', [make_Header(mypara), sRet, make_Footer( conn, mypara ) ]);
150 | exit;
151 | end;
152 |
153 | // validate input
154 | if length( usrFrm.pwd ) < 6 then
155 | begin
156 | sRet := sUpdate (sRet, '%%1', 'Ihr Passwort muss mindesten 6 Zeichen lang sein.');
157 | sRet := sUpdate (sRet, '%%2', 'Bitte korrigieren ..');
158 | Render('bbs_accnt.html', [make_Header(mypara), sRet, make_Footer( conn, mypara ) ]);
159 | exit;
160 | end;
161 |
162 | if usrFrm.pwd <> vPWD2 then
163 | begin
164 | sRet := sUpdate (sRet, '%%1', 'Passwort und Passwortbestätigung sind ungleich.');
165 | sRet := sUpdate (sRet, '%%2', 'Bitte korrigieren ..');
166 | Render('bbs_accnt.html', [make_Header(mypara), sRet, make_Footer( conn, mypara) ]);
167 | exit;
168 | end;
169 |
170 | // check if user already exists
171 | ReadUsr ( conn, ' where name="' + TRIM(usrFrm.Name) + '"', usrFrm );
172 | if usrFrm.iduser <> '' then
173 | begin
174 | sRet := sUpdate (sRet, '%%1', 'Der Benutzername: ' + usrFrm.Name + ' ist leider schon vergeben. ');
175 | sRet := sUpdate (sRet, '%%2', 'Bitte geben Sie einen anderen Namen ein.');
176 | Render('bbs_accnt.html', [make_Header(mypara), sRet, make_Footer( conn, mypara) ]);
177 | exit;
178 | end;
179 |
180 | // insert new user
181 | usrFrm.pwd := encrypt(usrFrm.pwd);
182 | usrFrm.RegisterIP := TheRequest.RemoteAddress;
183 | User_insert( BrookFCLFCGIBroker.conn, usrFrm );
184 |
185 | // read again to get recid of new user
186 | ReadUsr ( BrookFCLFCGIBroker.conn, ' where name="' + TRIM(usrFrm.Name) + '"', usrFrm );
187 | if usrFrm.iduser = '' then
188 | begin
189 | sRet := ' Account Info: Verbindungsfehler. Bitte später versuchen..
' +
190 | '';
191 | Render('bbs_accnt.html', [make_Header(mypara),
192 | sRet,
193 | make_Footer( BrookFCLFCGIBroker.conn, mypara) ]);
194 | exit;
195 | end;
196 |
197 | // Insert job 'regmail'
198 | myJob.inquirer := conn.UserName;
199 | myJob.inqIP := TheRequest.RemoteAddress;
200 | myJob.iduser := usrFrm.iduser;
201 | myJob.Action := 'regmail';
202 | myJob.Intervall := '0';
203 | myJob.Context := '|';
204 | job_insert ( BrookFCLFCGIBroker.conn, myJob );
205 |
206 | // render
207 | sRet := ' Account Info: Account erstellt. Sie erhalten eine Mail mit einem Aktivierungslink an die Mail Adresse ' +
208 | usrFrm.MailAdress + '
';
209 | Render('bbs_accnt.html', [make_Header(mypara),
210 | sRet,
211 | make_Footer( conn, mypara) ]);
212 |
213 | end;
214 |
215 |
216 |
217 | initialization
218 | TAccount.Register('accnt');
219 | TApprove.Register('approve');
220 |
221 | end.
222 |
223 |
--------------------------------------------------------------------------------
/upload.pas:
--------------------------------------------------------------------------------
1 | unit Upload;
2 |
3 | {$mode objfpc}{$H+}
4 |
5 | interface
6 |
7 | uses
8 | BrookAction, BrookConsts, BrookUtils, HTTPDefs, SysUtils;
9 |
10 | type
11 | TTest = class(TBrookAction)
12 | public
13 | procedure Get; override;
14 | procedure Post; override;
15 | end;
16 |
17 | const
18 | RESULT =
19 | 'All files:' + BR + LF + '%s' + BR + BR + LF +
20 | 'All files saved in:' + BR + LF + '%s';
21 |
22 | implementation
23 |
24 | procedure TTest.Get;
25 | begin
26 | Write({$i head.inc}, [{$i form.inc}]);
27 | end;
28 |
29 | procedure TTest.Post;
30 | var
31 | I: Integer;
32 | VFiles, VSep: string;
33 | VFormItem: TUploadedFile;
34 | begin
35 | VFiles := '';
36 | VSep := '||';
37 | for I := 0 to Pred(Files.Count) do
38 | begin
39 | VFormItem := Files[I];
40 | if VFormItem.FileName <> '' then
41 | VFiles += VFormItem.FileName + VSep;
42 | end;
43 | Write({$i head.inc},
44 | [Format(RESULT, [VFiles, BrookSettings.DirectoryForUploads])]);
45 | end;
46 |
47 | initialization
48 | TTest.Register('upload');
49 |
50 | end.
51 |
52 |
--------------------------------------------------------------------------------
/upst.pas:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////
2 | // project : bbs_fcgi
3 | // author : Ralph Berger
4 | // created : 10.03.14
5 | // file : upst.pas
6 | // show user posts for select or current user
7 | // modified : 24.04.2014 BF 2.6.4 -> BF 3.0.0
8 |
9 | unit upst;
10 |
11 | {$mode objfpc}{$H+}
12 |
13 | interface
14 |
15 | uses
16 | BrookAction, BrookFCLFCGIBroker, BrookConsts, Classes, SysUtils, Variants,
17 | FmtBCD, sqldb, blowcryp, mapping, menu;
18 |
19 |
20 | type
21 | TUpst = class(TBrookAction)
22 | public
23 | procedure Get; override;
24 | end;
25 |
26 |
27 | implementation
28 |
29 |
30 | procedure TUpst.Get;
31 | Var
32 | i,lastID: integer;
33 | sBody, sTmp : String;
34 | usrFrm1 : usrInfType;
35 | myPara : paraType;
36 | mySessn : sessInfType;
37 | query : TSQLQuery;
38 |
39 |
40 | begin
41 |
42 | // read paras
43 | myPara.VSession := Params.Values['sesn'];
44 | myPara.sID := Params.Values['ID'];
45 | // check session
46 | mypara.sip:= TheRequest.RemoteAddress;
47 | if NOT isSessionValid( mypara ) then
48 | begin
49 | Render(err_page, [myPara.lastError]);
50 | exit;
51 | end;
52 |
53 | // session callback target
54 | paraTypeInit('upst?ID=' + myPara.sID, myPara );
55 | mypara.sCmd := '1'; // '1' full menus
56 | // read sesion info
57 | mySessn.id := mypara.VSession;
58 | sesn_Read( BrookFCLFCGIBroker.conn, mySessn );
59 | sesn_copy_para( mySessn, myPara );
60 |
61 | // set session info
62 | if myPara.sID = '' then myPara.sID := IntToStr( myPara.userID ); // show logon user postings
63 | mypara.sCmd := '1'; // '1' full menus
64 |
65 | // set display order
66 | case myPara.v_order of
67 | '0' : sTmp := '' ;
68 | '1' : sTmp := ' ORDER BY topics.forum_id';
69 | '2' : sTmp := ' ORDER BY topics.topic_text';
70 | '3' : sTmp := ' ORDER BY topics.ctime';
71 | end;
72 |
73 |
74 | // read session user
75 | ReadUsr( BrookFCLFCGIBroker.conn, 'where iduser=' + mypara.sID, usrFrm1 );
76 | sBody := sUpdate( usrTbl,'%%0', showUsrImage(usrFrm1) );
77 | sBody := sUpdate( sBody, '%%1', count_usr_themes(BrookFCLFCGIBroker.conn, usrFrm1) );
78 | sBody := sUpdate( sBody, '%%2', count_usr_posts(BrookFCLFCGIBroker.conn, usrFrm1) + showUsrInfo(usrFrm1) );
79 |
80 | myPara.Text2 := usrFrm1.Name;
81 |
82 | // read forums and child posts
83 | query := TSQLQuery.Create(nil);
84 | query.DataBase := BrookFCLFCGIBroker.conn;
85 | query.SQL.Text := 'SELECT * FROM topics left join posts on ( topics.id = posts.forum_id ) ' +
86 | 'WHERE topics.poster =' + mypara.sID + ' OR posts.user_id =' + mypara.sID +
87 | sTmp + // set order
88 | ' limit ' + // limit start,stop
89 | IntToStr( StrToInt( mySessn.v_page ) * PageItems )
90 | + ',' + IntToStr( StrToInt( mySessn.v_page ) * PageItems + PageItems+1 );
91 | query.Open;
92 |
93 | i := 0;
94 | while not query.EOF do
95 | begin
96 | if query.FieldByName('forum_id').AsInteger <> lastID then
97 | begin
98 | sTmp := sUpdate( tpcTbl,'%%3', query.FieldByName('title').AsString );
99 | sTmp := sUpdate( sTmp, '%%4', query.FieldByName('ctime').AsString );
100 | sTmp := sUpdate( sTmp, '%%5', query.FieldByName('topic_text').AsString );
101 | sBody += sTmp;
102 | end;
103 |
104 | if query.FieldByName('user_id').IsNull = false then
105 | begin
106 | sTmp := sUpdate( pstTbl,'%%6', query.FieldByName('post_time').AsString );
107 | sTmp := sUpdate( sTmp, '%%7', query.FieldByName('post_text').AsString );
108 | sBody += sTmp;
109 | end;
110 |
111 |
112 | lastID := query.FieldByName('id').AsInteger;
113 | i += 1;
114 | if i = PageItems then break;
115 | query.next;
116 | end;
117 |
118 | mypara.V_rec := IntToStr(lastID); // rec id
119 | myPara.v_eof := iif( query.EOF, '1', '0'); // eof flag
120 |
121 | // display
122 | Render('bbs_upst.html', [make_Header_UPosts( myPara ),
123 | sBody ,
124 | make_Footer( BrookFCLFCGIBroker.conn, myPara ) ]);
125 |
126 |
127 | // release mem
128 | query.active := false;
129 | query.free;
130 |
131 |
132 | end;
133 |
134 | initialization
135 | TUpst.Register('upst');
136 |
137 | end.
138 |
139 |
--------------------------------------------------------------------------------