- Timestamp:
- Sep 18, 2015, 7:39:03 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/docs/Changelog
r487 r488 1 1 4.1.0: 2 * fix quirks with Linux audit support 3 * implement 'silent check' (requested feature) 2 4 * fix call of self_check for exit on sigterm 3 5 * fix safe_logger() - uses the logger utility with a non-posix option -
trunk/include/samhain.h
r481 r488 134 134 #undef BAD 135 135 #define BAD S_FALSE 136 137 #define SH_SILENT_FULL 2 138 #define SH_SILENT_STD 1 136 139 137 140 … … 398 401 extern volatile int sig_termfast; /* SIGTERM */ 399 402 extern volatile int sig_force_check; /* SIGTTOU */ 403 extern volatile int sig_force_silent; /* SIGTSTP */ 404 extern volatile int sh_global_check_silent; 400 405 extern volatile int sh_load_delta_flag; 401 406 -
trunk/include/sh_files.h
r481 r488 24 24 void sh_audit_commit (); 25 25 void sh_audit_delete_all (); 26 char * sh_audit_fetch (char * file, time_t time, char * result, size_t rsize);26 char * sh_audit_fetch (char * file, time_t mtime, time_t ctime, char * result, size_t rsize); 27 27 28 28 struct sh_dirent { -
trunk/man/samhain.8
r481 r488 231 231 according to the timing options in the 232 232 configuration file. 233 .TP 234 [\-i|\-\-interactive] 235 Run update in interactive mode. 236 .TP 237 [\-\-listfile=PATH] 238 Run the update with a list of 'good' filepaths given in file (one path per line). 239 233 240 234 241 .PP -
trunk/src/samhain.c
r487 r488 122 122 volatile int sig_termfast; /* SIGTERM */ 123 123 volatile int sig_force_check; /* SIGTTOU */ 124 volatile int sig_force_silent; /* SIGTSTP */ 125 volatile int sh_global_check_silent; 124 126 volatile int sh_load_delta_flag; 125 127 long int eintr__result; … … 343 345 sig_termfast = 0; /* SIGTERM */ 344 346 sig_force_check = 0; /* SIGTTOU */ 347 sig_force_silent = 0; /* SIGTSTP */ 348 sh_global_check_silent = 0; 345 349 sh_load_delta_flag = 0; 346 350 strcpy ( sh_sig_msg, _("None")); … … 1228 1232 } 1229 1233 1234 static int sh_flag_silent = S_FALSE; 1235 1236 int sh_set_silent_full (const char * str) 1237 { 1238 int status = sh_util_flagval(str, &sh_flag_silent); 1239 return status; 1240 } 1241 1230 1242 1231 1243 void do_reconf() … … 1378 1390 } 1379 1391 1380 if (sig_force_check == 1) /* SIGTTOU */1392 if (sig_force_check == 1) /* SIGTTOU / SIGTSTP */ 1381 1393 { 1382 1394 TPT((0, FIL__, __LINE__, _("msg=<Check run triggered.>\n"))); 1383 1395 *flag_check_1 = 1; *flag_check_2 = 1; 1384 sig_force_check = 0; --sig_raised; 1396 sig_force_check = 0; --sig_raised; 1397 if (sig_force_silent) 1398 { 1399 sig_force_silent = 0; 1400 sh_global_check_silent = (sh_flag_silent == S_FALSE) ? SH_SILENT_STD : SH_SILENT_FULL; 1401 } 1385 1402 sh_sem_trylock(); 1386 1403 } … … 1470 1487 /* Need to contact the server. 1471 1488 */ 1472 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_2); 1489 if (sh_global_check_silent < SH_SILENT_FULL) 1490 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_2); 1473 1491 1474 1492 if (sig_raised > 0 && sh_load_delta_flag > 0) /* DELTA Command */ … … 2119 2137 (void) sh_files_chk (); 2120 2138 2121 if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); continue; }2139 if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); sh_global_check_silent = 0; continue; } 2122 2140 /* 2123 2141 * check for files not visited … … 2129 2147 } 2130 2148 2131 if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); continue; }2149 if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); sh_global_check_silent = 0; continue; } 2132 2150 2133 2151 /* reset … … 2136 2154 sh_dirs_reset (); 2137 2155 2138 if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); continue; }2156 if (sig_urgent > 0) { sh_sem_unlock(sh.statistics.files_report); sh_global_check_silent = 0; continue; } 2139 2157 2140 2158 sh_files_reset (); … … 2150 2168 (void) sh_prelink_run (NULL, NULL, 0, 0); 2151 2169 2152 if (sig_urgent > 0) continue;2170 if (sig_urgent > 0) { sh_global_check_silent = 0; continue; } 2153 2171 2154 2172 runtim = time(NULL) - sh.statistics.time_start; … … 2156 2174 2157 2175 if ((sh.statistics.dirs_checked == 0) && 2158 (sh.statistics.files_checked == 0)) 2176 (sh.statistics.files_checked == 0) && 2177 (sh_global_check_silent < SH_SILENT_FULL)) 2159 2178 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_0); 2160 2179 … … 2174 2193 sh.statistics.bytes_speed = (unsigned long) st_1; 2175 2194 2176 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_1, 2177 (long) runtim, 2178 0.001 * st_1); 2195 if (sh_global_check_silent < SH_SILENT_FULL) 2196 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_CHECK_1, 2197 (long) runtim, 2198 0.001 * st_1); 2179 2199 2180 2200 if (sh.flag.checkSum != SH_CHECK_INIT) 2181 2201 sh_efile_report(); 2182 2202 } 2183 sh.fileCheck.alarm_last = time (NULL); 2184 2203 2204 if (0 == sh_global_check_silent) 2205 sh.fileCheck.alarm_last = time (NULL); 2206 2207 sh_global_check_silent = 0; 2208 2185 2209 if (sig_urgent > 0) continue; 2186 2210 -
trunk/src/sh_audit.c
r434 r488 28 28 #include <errno.h> 29 29 #include <unistd.h> 30 #include <fcntl.h> 31 #include <sys/stat.h> 32 33 #include "samhain.h" 34 #include "sh_error.h" 30 35 31 36 #if !defined(SH_COMPILE_STATIC) && defined(__linux__) && defined(HAVE_AUPARSE_H) && defined(HAVE_AUPARSE_LIB) 32 37 #include <auparse.h> 33 38 34 #include "samhain.h"35 #include "sh_error.h"36 39 #include "sh_extern.h" 37 40 #include "sh_utils.h" … … 103 106 } 104 107 105 static char * doAuparse (c har * file, time_t time, char * result, size_t rsize)108 static char * doAuparse (const char * file, time_t time, int tol, char * result, size_t rsize, int redo_flag) 106 109 { 107 110 struct recordState state; 108 111 struct recordState stateFetched; 109 112 unsigned int found_flag = 0; 113 110 114 auparse_state_t * au = auparse_init(AUSOURCE_LOGS, NULL); 111 115 … … 131 135 if (time != 0) 132 136 { 133 ausearch_add_timestamp_item(au, ">=", time- 1, 0, AUSEARCH_RULE_AND);134 ausearch_add_timestamp_item(au, "<=", time+ 1, 0, AUSEARCH_RULE_AND);137 ausearch_add_timestamp_item(au, ">=", time-tol, 0, AUSEARCH_RULE_AND); 138 ausearch_add_timestamp_item(au, "<=", time+tol, 0, AUSEARCH_RULE_AND); 135 139 } 136 140 … … 152 156 { 153 157 memcpy(&state, &stateFetched, sizeof(state)); 158 ++found_flag; 154 159 } 155 160 auparse_next_event(au); 156 161 } 157 162 163 if (found_flag == 0 && redo_flag == S_FALSE) 164 { 165 size_t len = strlen(file); 166 char * path = SH_ALLOC(len + 2); 167 char * altres; 168 169 sl_strlcpy(path, file, len+2); 170 path[len] = '/'; path[len+1] = '\0'; 171 auparse_destroy(au); 172 173 altres = doAuparse(path, time, tol, result, rsize, S_TRUE); 174 175 SH_FREE(path); 176 return altres; 177 } 178 158 179 if (0 == strcmp(state.success, "yes")) 159 180 { … … 189 210 * The 'result' array should be sized ~256 char. 190 211 */ 191 char * sh_audit_fetch (char * file, time_t time, char * result, size_t rsize)212 char * sh_audit_fetch (char * file, time_t mtime, time_t ctime, char * result, size_t rsize) 192 213 { 193 214 char * res = NULL; … … 195 216 if (sh_audit_checkdaemon() >= 0) 196 217 { 197 res = doAuparse (file, time, result, rsize); 218 time_t new; 219 char buf[64]; 220 221 if (mtime >= ctime) { new = mtime; } 222 else { new = ctime; } 223 224 res = doAuparse (file, new, 1, result, rsize, S_FALSE); 198 225 199 226 if (!res) 200 227 { 201 res = doAuparse (file, 0, result, rsize);228 res = doAuparse (file, new, 3, result, rsize, S_FALSE); 202 229 } 230 203 231 } 204 232 return res; … … 226 254 } 227 255 256 static int sh_audit_isdir(const char * file) 257 { 258 struct stat buf; 259 260 if ( (0 == lstat (file, &buf)) && S_ISDIR(buf.st_mode)) 261 return S_TRUE; 262 return S_FALSE; 263 } 264 228 265 static void sh_audit_mark_int (const char * file) 229 266 { … … 246 283 char * safe; 247 284 char ctl[64]; 285 char a1[32]; 286 char a2[32]; 287 char a3[32]; 248 288 249 289 sl_snprintf(command, len, _("%s -w %s -p wa -k samhain"), … … 256 296 safe, 257 297 _("sh_audit_mark") ); 298 258 299 SH_FREE(safe); 259 300 … … 261 302 sl_strlcpy(command, file, len); 262 303 263 sh_ext_system(ctl, ctl, "-w", command, "-p", "wa", "-k", _("samhain"), NULL); 264 304 sl_strlcpy(a3, _("samhain"), sizeof(a3)); 305 sh_ext_system(ctl, ctl, "-w", command, "-p", "wa", "-k", a3, NULL); 306 307 /* Placing a watch on a directory will not place a watch on the 308 * directory inode, so we do this explicitely. 309 */ 310 if (S_TRUE == sh_audit_isdir(file)) 311 { 312 safe = sh_util_safe_name(file); 313 sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 314 0, MSG_E_SUBGPATH, 315 _("Add path watch for directory"), 316 _("sh_audit_mark_int"), safe ); 317 SH_FREE(safe); 318 sl_strlcpy(command, _("path="), len); 319 sl_strlcat(command, file, len); 320 sl_strlcpy(a1, _("always,exit"), sizeof(a1)); 321 sl_strlcpy(a2, _("perm=wa"), sizeof(a2)); 322 sh_ext_system(ctl, ctl, "-a", a1, "-F", command, "-F", a2, "-k", a3, NULL); 323 } 265 324 SH_FREE(command); 266 325 } … … 278 337 { 279 338 struct aud_list * this = SH_ALLOC(sizeof(struct aud_list)); 339 size_t len = strlen(file); 340 280 341 this->file = sh_util_strdup(file); 342 if ((len > 1) && (file[len-1] == '/')) 343 this->file[len-1] = '\0'; 344 281 345 this->next = mark_these; 282 346 mark_these = this; … … 284 348 } 285 349 350 /* Check whether it is already covered by a higher directory 351 */ 286 352 static int test_exchange (struct aud_list * this, char * file) 287 353 { … … 312 378 if (0 == strncmp(s0, s1, len1 + 1)) 313 379 { 380 size_t len = strlen(file); 314 381 SH_FREE(this->file); 315 382 this->file = sh_util_strdup(file); 383 if ((len > 1) && (file[len-1] == '/')) 384 this->file[len-1] = '\0'; 316 385 ret = 0; 317 386 } … … 324 393 } 325 394 395 /* Place a path on the list of of paths to be watched 396 */ 326 397 void sh_audit_mark (char * file) 327 398 { … … 335 406 while (this) 336 407 { 408 /* Check whether it is already covered by a higher 409 * directory 410 */ 337 411 if (0 == test_exchange(this, file)) 338 412 return; … … 464 538 /* HAVE_AUPARSE_H */ 465 539 #else 466 char * sh_audit_fetch (char * file, time_t time, char * result, size_t rsize)540 char * sh_audit_fetch (char * file, time_t mtime, time_t ctime, char * result, size_t rsize) 467 541 { 468 542 (void) file; 469 (void) time; 543 (void) mtime; 544 (void) ctime; 470 545 (void) result; 471 546 (void) rsize; … … 476 551 { 477 552 (void) file; 553 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN, 554 _("Setting audit watch not supported"), 555 _("sh_audit_mark")); 478 556 return; 479 557 } -
trunk/src/sh_error.c
r481 r488 1106 1106 goto exit_here; 1107 1107 } 1108 1108 1109 #if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE) 1110 if ((sh_global_check_silent > SH_SILENT_STD) && 1111 (((1 << FIL) & (1 << class)) != 0)) 1112 { 1113 goto exit_here; 1114 } 1115 #endif 1109 1116 1110 1117 /* Allocate space for the message. -
trunk/src/sh_fInotify.c
r481 r488 511 511 512 512 SH_MUTEX_LOCK(mutex_thread_nolog); 513 sh_error_handle (level, FIL__, __LINE__, 0, MSG_FI_MISS, tmp); 513 if (!sh_global_check_silent) 514 sh_error_handle (level, FIL__, __LINE__, 0, MSG_FI_MISS, tmp); 514 515 SH_MUTEX_UNLOCK(mutex_thread_nolog); 515 516 ++sh.statistics.files_report; -
trunk/src/sh_files.c
r481 r488 393 393 if (tmp == NULL) 394 394 tmp = sh_util_safe_name (ptr->name); 395 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 396 ShDFLevel[ptr->class] : 397 ShDFLevel[SH_ERR_T_FILE], 398 FIL__, __LINE__, 0, MSG_FI_MISS, 399 tmp); 395 if (!sh_global_check_silent) 396 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 397 ShDFLevel[ptr->class] : 398 ShDFLevel[SH_ERR_T_FILE], 399 FIL__, __LINE__, 0, MSG_FI_MISS, 400 tmp); 400 401 ++sh.statistics.files_report; 401 402 } … … 447 448 if (tmp == NULL) 448 449 tmp = sh_util_safe_name (ptr->name); 449 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE)? 450 ShDFLevel[ptr->class] : 451 ShDFLevel[SH_ERR_T_FILE], 452 FIL__, __LINE__, 0, MSG_FI_MISS, 453 tmp); 450 if (!sh_global_check_silent) 451 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE)? 452 ShDFLevel[ptr->class] : 453 ShDFLevel[SH_ERR_T_FILE], 454 FIL__, __LINE__, 0, MSG_FI_MISS, 455 tmp); 454 456 ++sh.statistics.files_report; 455 457 } … … 953 955 else if (0 == strcmp(myword, _("TXT"))) 954 956 sh_files_set_mask (mask, MODI_TXT, act); 955 /* get content */957 /* get audit report */ 956 958 else if (0 == strcmp(myword, _("AUDIT"))) 957 959 sh_files_set_mask (mask, MODI_AUDIT, act); … … 1157 1159 if (MODI_AUDIT_ENABLED(check_flags)) 1158 1160 { 1161 sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGPATH, 1162 _("Setting audit watch"), 1163 _("sh_files_push_file_int"), str_s); 1159 1164 sh_audit_mark(str_s); 1160 1165 } … … 1577 1582 ShDFLevel[SH_ERR_T_DIR])) { 1578 1583 tmp = sh_util_safe_name (ptr->name); 1579 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 1580 ShDFLevel[ptr->class] : 1581 ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 1582 0, MSG_FI_MISS, tmp); 1584 if (!sh_global_check_silent) 1585 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 1586 ShDFLevel[ptr->class] : 1587 ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 1588 0, MSG_FI_MISS, tmp); 1583 1589 ++sh.statistics.files_report; 1584 1590 SH_FREE(tmp); … … 1601 1607 */ 1602 1608 tmp = sh_util_safe_name (ptr->name); 1603 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 1604 ShDFLevel[ptr->class] : 1605 ShDFLevel[SH_ERR_T_DIR], 1606 FIL__, __LINE__, 0, MSG_FI_ADD, 1607 tmp); 1609 if (!sh_global_check_silent) 1610 sh_error_handle ((ptr->class == SH_LEVEL_ALLIGNORE) ? 1611 ShDFLevel[ptr->class] : 1612 ShDFLevel[SH_ERR_T_DIR], 1613 FIL__, __LINE__, 0, MSG_FI_ADD, 1614 tmp); 1608 1615 ++sh.statistics.files_report; 1609 1616 SH_FREE(tmp); … … 1778 1785 if (MODI_AUDIT_ENABLED(check_flags)) 1779 1786 { 1787 sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGPATH, 1788 _("Setting audit watch"), 1789 _("sh_files_push_file_int"), tail); 1780 1790 sh_audit_mark(tail); 1781 1791 } … … 2156 2166 if (theFile->c_mode[0] != 'd') 2157 2167 { 2158 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0, 2159 MSG_FI_NODIR, 2160 tmpname); 2168 if (!sh_global_check_silent) 2169 sh_error_handle (ShDFLevel[SH_ERR_T_DIR], FIL__, __LINE__, 0, 2170 MSG_FI_NODIR, 2171 tmpname); 2161 2172 ++sh.statistics.files_nodir; 2162 2173 if (theFile->attr_string) SH_FREE(theFile->attr_string); -
trunk/src/sh_hash.c
r481 r488 248 248 249 249 SH_MUTEX_LOCK(mutex_thread_nolog); 250 sh_error_handle (level, FIL__, __LINE__, 0, 251 MSG_FI_MISS2, tmp, str); 250 if (!sh_global_check_silent) 251 sh_error_handle (level, FIL__, __LINE__, 0, 252 MSG_FI_MISS2, tmp, str); 252 253 SH_MUTEX_UNLOCK(mutex_thread_nolog); 253 254 ++sh.statistics.files_report; … … 363 364 theFile = sh_hash_create_ft (p, fileHash); 364 365 str = all_items(theFile, fileHash, 0); 365 sh_error_handle (level, FIL__, __LINE__, 0, 366 MSG_FI_MISS2, tmp, str); 366 if (!sh_global_check_silent) 367 sh_error_handle (level, FIL__, __LINE__, 0, 368 MSG_FI_MISS2, tmp, str); 367 369 ++sh.statistics.files_report; 368 370 SH_FREE(str); … … 405 407 theFile = sh_hash_create_ft (p, fileHash); 406 408 str = all_items(theFile, fileHash, 0); 407 sh_error_handle (level, FIL__, __LINE__, 0, 408 MSG_FI_MISS2, tmp, str); 409 if (!sh_global_check_silent) 410 sh_error_handle (level, FIL__, __LINE__, 0, 411 MSG_FI_MISS2, tmp, str); 409 412 ++sh.statistics.files_report; 410 413 SH_FREE(str); … … 1812 1815 str = all_items (theFile, fileHash, 1); 1813 1816 1814 sh_error_handle (log_severity, FIL__, __LINE__, 0, 1815 MSG_FI_ADD2, 1816 tmp, str); 1817 if (!sh_global_check_silent) 1818 sh_error_handle (log_severity, FIL__, __LINE__, 0, 1819 MSG_FI_ADD2, 1820 tmp, str); 1817 1821 ++sh.statistics.files_report; 1818 1822 SH_FREE(str); … … 2540 2544 { 2541 2545 char result[256]; 2542 2543 if (NULL != sh_audit_fetch (theFile->fullpath, theFile->mtime, result, sizeof(result))) 2546 2547 sh_error_handle (SH_ERR_INFO, FIL__, __LINE__, 2548 0, MSG_E_SUBGPATH, 2549 _("Fetching audit record"), 2550 _("sh_hash"), theFile->fullpath ); 2551 2552 if (NULL != sh_audit_fetch (theFile->fullpath, theFile->mtime, theFile->ctime, result, sizeof(result))) 2544 2553 { 2545 2554 #ifdef SH_USE_XML … … 2565 2574 ****************************************************/ 2566 2575 tmp_path = sh_util_safe_name(theFile->fullpath); 2567 sh_error_handle(log_severity, FIL__, __LINE__, 2568 (long) modi_mask, MSG_FI_CHAN, 2569 (policy_override == NULL) ? _(policy[class]):log_policy, 2570 change_code, tmp_path, msg); 2576 if (!sh_global_check_silent) 2577 sh_error_handle(log_severity, FIL__, __LINE__, 2578 (long) modi_mask, MSG_FI_CHAN, 2579 (policy_override == NULL) ? _(policy[class]):log_policy, 2580 change_code, tmp_path, msg); 2571 2581 ++sh.statistics.files_report; 2572 2582 -
trunk/src/sh_readconf.c
r481 r488 871 871 extern int sh_set_schedule_one(const char * str); 872 872 extern int sh_set_schedule_two(const char * str); 873 extern int sh_set_silent_full (const char * str); 873 874 #endif 874 875 #if defined (SH_WITH_SERVER) … … 1101 1102 { N_("setprelinkchecksum"), SH_SECTION_MISC, SH_SECTION_NONE, 1102 1103 sh_prelink_set_hash }, 1104 1105 { N_("setfullsilent"), SH_SECTION_MISC, SH_SECTION_NONE, 1106 sh_set_silent_full }, 1103 1107 1104 1108 /* client or standalone -
trunk/src/sh_unix.c
r487 r488 666 666 sig_force_check = 1; sh_sem_trylock(); } 667 667 #endif 668 #ifdef SIGTSTP 669 if (mysignal == SIGTSTP) { 670 sig_force_check = 1; sig_force_silent = 1; sh_sem_trylock(); } 671 #endif 668 672 #ifdef SIGTTIN 669 673 if (mysignal == SIGTTIN) … … 841 845 retry_sigaction(FIL__, __LINE__, SIGALRM, &ignact, &oldact); 842 846 #endif 843 #ifdef SIGTSTP844 retry_sigaction(FIL__, __LINE__, SIGTSTP, &ignact, &oldact);845 #endif846 847 847 848 #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) … … 852 853 retry_sigaction(FIL__, __LINE__, SIGTTOU, &ignact, &oldact); 853 854 #endif 855 #ifdef SIGTSTP 856 if (goDaemon == 1) 857 retry_sigaction(FIL__, __LINE__, SIGTSTP, &act2, &oldact); 858 else 859 retry_sigaction(FIL__, __LINE__, SIGTSTP, &ignact, &oldact); 860 #endif 854 861 #ifdef SIGTTIN 855 862 if (goDaemon == 1) … … 859 866 #endif 860 867 #else 868 #ifdef SIGTSTP 869 retry_sigaction(FIL__, __LINE__, SIGTSTP, &ignact, &oldact); 870 #endif 861 871 #ifdef SIGTTOU 862 872 retry_sigaction(FIL__, __LINE__, SIGTTOU, &ignact, &oldact);
Note:
See TracChangeset
for help on using the changeset viewer.