Changeset 2204 for trunk/auto-reply
- Timestamp:
- 08/16/00 08:39:45 (8 years ago)
- Location:
- trunk/auto-reply
- Files:
-
- 5 modified
-
configure.in (modified) (2 diffs)
-
licq_autoreply.conf (modified) (1 diff)
-
src/autoreply.cpp (modified) (8 diffs)
-
src/autoreply.h (modified) (2 diffs)
-
src/main.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/auto-reply/configure.in
r2013 r2204 6 6 7 7 dnl All versioning is done via the following line 8 AM_INIT_AUTOMAKE(Licq-AutoReply, 0.17)8 AM_INIT_AUTOMAKE(Licq-AutoReply, 1.0) 9 9 AM_CONFIG_HEADER(config.h) 10 10 … … 36 36 dnl Checks for header files. 37 37 AC_HEADER_STDC 38 AC_CHECK_HEADERS(errno.h pwd.h sys/time.h )38 AC_CHECK_HEADERS(errno.h pwd.h sys/time.h paths.h) 39 39 AC_HEADER_TIME 40 40 LICQ_SYS_ERRLIST -
trunk/auto-reply/licq_autoreply.conf
r794 r2204 2 2 # Edit and copy to ~/.licq 3 3 4 # the program to run for output to send in the message5 4 [Reply] 6 Program=/usr/games/fortune 5 # The program to run for output to send in the message. 6 # "talkback" might be any program or script. 7 Program = talkback 7 8 9 # This is a string which will be parsed for user % symbols 10 # and then appended to the above command. 11 # This example passes the uin and then the alias in quotes 12 # So the final command might be: 13 # talkback -u 3456789 -a 'coolguy' 14 # WARNING: be careful passing the alias, name etc as they could 15 # contain exploits such as "evil_alias; rm -rf ~". 16 # Always quote anything that could contain text. 17 Arguments = -u %u -a '%a' 18 19 # This flag tells the plugin whether or not the command 20 # expects the incoming message as standard input 21 # If set to 1 then the program will be fed the incoming 22 # message to standard input. 23 PassMessage = 0 24 25 26 # Here is a simple example which will bounce the event 27 # right back to the user: 28 # 29 # Program = cat 30 # Arguments = 31 # PassMessage = 1 32 # 33 # 34 # Here is an example which simply sends a fortune back to 35 # the user: 36 # 37 # Program = /usr/games/fortune 38 # Arguments = 39 # PassMessage = 0 40 # 41 -
trunk/auto-reply/src/autoreply.cpp
r2099 r2204 7 7 #include <stdio.h> 8 8 #include <stdlib.h> 9 #include <sys/wait.h> 10 #include <sys/time.h> 11 #include <signal.h> 9 12 #ifdef HAVE_ERRNO_H 10 13 #include <errno.h> … … 12 15 extern int errno; 13 16 #endif 17 #ifdef HAVE_PATHS_H 18 #include <paths.h> 19 #else 20 #define _PATH_BSHELL "/bin/sh" 21 #endif 22 14 23 15 24 #include "autoreply.h" … … 74 83 conf.SetSection("Reply"); 75 84 conf.ReadStr("Program", m_szProgram); 85 conf.ReadStr("Arguments", m_szArguments, ""); 86 conf.ReadBool("PassMessage", m_bPassMessage, false); 76 87 conf.CloseFile(); 77 88 … … 194 205 void CLicqAutoReply::ProcessEvent(ICQEvent *e) 195 206 { 207 CUserEvent *user_event; 208 209 if (e->Result() != EVENT_ACKED) 210 { 211 if (e->Command() == ICQ_CMDxTCP_START && 212 (e->SubCommand() != ICQ_CMDxSUB_CHAT && 213 e->SubCommand() != ICQ_CMDxSUB_FILE)) 214 { 215 user_event = e->UserEvent(); 216 CICQEventTag *tag = licqDaemon->icqSendMessage(e->Uin(), user_event->Text(), false, 217 ICQ_TCPxMSG_URGENT); //urgent, because, hey, he asked us, right? 218 delete tag; 219 } 220 } 221 196 222 delete e; 197 223 } … … 216 242 else 217 243 { 218 bool r = AutoReplyEvent(nUin );244 bool r = AutoReplyEvent(nUin, e); 219 245 if (m_bDelete && r) 220 246 { … … 227 253 228 254 229 bool CLicqAutoReply::AutoReplyEvent(unsigned long nUin) 230 { 231 FILE *output; 232 char m_szMessage[4096]; 255 bool CLicqAutoReply::AutoReplyEvent(unsigned long nUin, CUserEvent *event) 256 { 257 char m_szMessage[4096], szCommand[4096]; 233 258 char c; 234 259 int pos = 0; … … 238 263 m_szMessage[i] = '\0'; 239 264 } 240 output = popen (m_szProgram, "r"); 241 if (!output) 242 { 243 gLog.Warn("%sCould not execute %s\n", L_AUTOREPxSTR, m_szProgram); 265 266 char *buf = szCommand; 267 buf += sprintf(buf, "%s ", m_szProgram); 268 ICQUser *u = gUserManager.FetchUser(nUin, LOCK_R); 269 u->usprintf(buf, m_szArguments); 270 gUserManager.DropUser(u); 271 272 if (!POpen(szCommand)) 273 { 274 gLog.Warn("%sCould not execute %s\n", L_AUTOREPxSTR, szCommand); 244 275 return false; 245 276 } 246 while (((c = fgetc(output)) != EOF) && (pos < 4096)) 277 if (m_bPassMessage) 278 { 279 fprintf(fStdIn, "%s\n", event->Text()); 280 fclose(fStdIn); 281 fStdIn = NULL; 282 } 283 284 while (((c = fgetc(fStdOut)) != EOF) && (pos < 4096)) 247 285 { 248 286 m_szMessage[pos++] = c; 249 287 } 250 pclose (output); 288 PClose(); 289 251 290 char *szText = new char[4096 + 256]; 252 291 sprintf(szText, "%s", m_szMessage); 253 CICQEventTag *tag = licqDaemon->icqSendMessage(nUin, szText, false,254 ICQ_TCPxMSG_ NORMAL);292 CICQEventTag *tag = licqDaemon->icqSendMessage(nUin, szText, true, 293 ICQ_TCPxMSG_URGENT); 255 294 delete []szText; 256 295 257 ICQUser *u = gUserManager.FetchUser(nUin, LOCK_R);296 u = gUserManager.FetchUser(nUin, LOCK_R); 258 297 if (u == NULL) return false; 259 298 … … 274 313 } 275 314 315 316 317 bool CLicqAutoReply::POpen(const char *cmd) 318 { 319 int pdes_out[2], pdes_in[2]; 320 321 if (pipe(pdes_out) < 0) return false; 322 if (pipe(pdes_in) < 0) return false; 323 324 switch (pid = fork()) 325 { 326 case -1: /* Error. */ 327 { 328 close(pdes_out[0]); 329 close(pdes_out[1]); 330 close(pdes_in[0]); 331 close(pdes_in[1]); 332 return false; 333 /* NOTREACHED */ 334 } 335 case 0: /* Child. */ 336 { 337 if (pdes_out[1] != STDOUT_FILENO) 338 { 339 dup2(pdes_out[1], STDOUT_FILENO); 340 close(pdes_out[1]); 341 } 342 close(pdes_out[0]); 343 if (pdes_in[0] != STDIN_FILENO) 344 { 345 dup2(pdes_in[0], STDIN_FILENO); 346 close(pdes_in[0]); 347 } 348 close(pdes_in[1]); 349 execl(_PATH_BSHELL, "sh", "-c", cmd, NULL); 350 _exit(127); 351 /* NOTREACHED */ 352 } 353 } 354 355 /* Parent; assume fdopen can't fail. */ 356 fStdOut = fdopen(pdes_out[0], "r"); 357 close(pdes_out[1]); 358 fStdIn = fdopen(pdes_in[1], "w"); 359 close(pdes_in[0]); 360 361 // Set both streams to line buffered 362 setvbuf(fStdOut, (char*)NULL, _IOLBF, 0); 363 setvbuf(fStdIn, (char*)NULL, _IOLBF, 0); 364 365 return true; 366 } 367 368 369 void CLicqAutoReply::PClose() 370 { 371 int r, pstat; 372 373 // Close the file descriptors 374 if (fStdOut != NULL) fclose(fStdOut); 375 if (fStdIn != NULL) fclose(fStdIn); 376 fStdOut = fStdIn = NULL; 377 378 // See if the child is still there 379 r = waitpid(pid, &pstat, WNOHANG); 380 // Return if child has exited or there was an inor 381 if (r == pid || r == -1) return; 382 383 // Give the process another .2 seconds to die 384 struct timeval tv = { 0, 200000 }; 385 select(0, NULL, NULL, NULL, &tv); 386 387 // Still there? 388 r = waitpid(pid, &pstat, WNOHANG); 389 if (r == pid || r == -1) return; 390 391 // Try and kill the process 392 if (kill(pid, SIGTERM) == -1) return; 393 394 // Give it 1 more second to die 395 tv.tv_sec = 1; 396 tv.tv_usec = 0; 397 select(0, NULL, NULL, NULL, &tv); 398 399 // See if the child is still there 400 r = waitpid(pid, &pstat, WNOHANG); 401 if (r == pid || r == -1) return; 402 403 // Kill the bastard 404 kill(pid, SIGKILL); 405 // Now he will die for sure 406 waitpid(pid, &pstat, 0); 407 } 408 409 -
trunk/auto-reply/src/autoreply.h
r2099 r2204 26 26 bool m_bExit, m_bEnabled, m_bDelete; 27 27 char *m_szStatus; 28 char m_szProgram[512]; 28 char m_szProgram[512], m_szArguments[512]; 29 bool m_bPassMessage; 29 30 30 31 CICQDaemon *licqDaemon; … … 37 38 38 39 void ProcessUserEvent(unsigned long, unsigned long); 39 bool AutoReplyEvent(unsigned long); 40 bool AutoReplyEvent(unsigned long, CUserEvent *); 41 42 bool POpen(const char *cmd); 43 void PClose(); 44 45 protected: 46 int pid; 47 FILE *fStdOut; 48 FILE *fStdIn; 40 49 41 50 }; -
trunk/auto-reply/src/main.cpp
r2154 r2204 42 42 const char *LP_Version() 43 43 { 44 static const char version[] = " 0.17";44 static const char version[] = "1.00"; 45 45 return version; 46 46 }
